阅读笔记——实战:OutOfMemoryError

two targets

One:验证java虚拟机规范中描述的各个运行时区域存储的内容;

Two:在工作中遇到OOM时能根据异常的信息快速判断是哪个区域的内存溢出,知道怎样的代码会导致这些区域内存溢出,以及如何处理。

-java堆溢出

java heap用来存放对象实例,不断的创建对象,并保证这些对象可达。在达到最大容量限制就会产生内存溢出。-Xmx, -Xms, -Xmn(Young)。-XX:+HeapDumpOnOutOfMemoryError可以在溢出时dump出当前的内存堆存储快照。

public class HeapOOM{
    static class OOMObject{}
    public static void main(String[] args){
        List<OOMObject> list = new ArrayList<OOMObject>();
        while(true){
            list.add(new OOMObject());
        }    
    }
}

 java.lang.OutOfMemoryError:Java heap space

 Dumping heap to java_pid3404.hprof...

 Heap dump file created [22045981 bytes in 0.662 secs]

内存泄露:无意义对象仍然存活,导致的异常。

内存溢出:对象确实都必要存活。

-JVM Stack&native method Stack OOM

如果线程请求的栈深度大于虚拟机允许的最大深度,StackOverflowError。

如果虚拟机在扩展栈时无法申请到足够的内存,OutOfMemoryError。

public class JavaVMStackSOF{
    private int stackLength = 1;
    private void stackLeak(){
        stackLength++;
        stackLeak();
    }
    public stack void main(String[] args){
        JavaVMStackSOF oom = new JavaVMStackSOF();
        try{
            oom.stackLeak();
        }catch(Throwable e){
            System.out.println("stack length:" +oom.stackLength);
            throw e;
        }
    }
}

 stack length:2402

 Exception in thread "main" java.lang.StackOverflowError

操作系统分配给每个进程的内存是有限制的,JVM提供了参数控制java堆(Xmx)和方法区(MaxPermSize)的内存大小,剩下的内存就由虚拟机栈(JVM Stack)和本地方法栈(Native Method Stack)瓜分。

public class JavaVMStackOOM {
    private void dontstop() {
        while (true){}
    }

    public void stackLeakByThread(){
        while (true){
            Thread thread = new Thread(new Runnable(){
                @Override
                 public void run(){
                    dontstop();
                 }
            });
            thread.start();
        }
    }

    public static void main(String[] args) {
        JavaVMStackOOM oom= new JavaVMStackOOM ();
        oom.stackLeakByThread();
    }
}

 运行结果:

Exception in thred “main” java.lang.OutOFMemoryError: unable to create new native thread

-Method Area & Runtime Constant Pool

运行时常量池是方法区的一部分

猜你喜欢

转载自yanfei0331.iteye.com/blog/2223759