美文网首页
JVM OOM异常会导致JVM退出吗?

JVM OOM异常会导致JVM退出吗?

作者: 7d972d5e05e8 | 来源:发表于2020-05-14 18:18 被阅读0次

    参考文章:JVM OOM异常会导致JVM退出吗?

    结论是:OOM是针对线程的,哪个线程OOM了,JVM是释放掉该线程所有的资源。然后其他线程继续运行,JVM不会退出。

    JVM退出的条件是:虚拟机内不存在非守护线程。

    下面是我的demo测试:

    public class OOMTest {
    
        public static void main(String[] args) throws InterruptedException {
            int i=0;
            while (true){
                if(i > 0){
                    System.out.println("main thread");
                    Thread.sleep(1000L);
                    continue;
                }
                Thread t1 = new Thread(() -> {
                    List<OOMObject>  refs = new ArrayList<>();
                    while (true){
                        OOMObject o1 = new OOMObject();
                        refs.add(o1);
                        System.out.println("thread-1申请1M");
                        try {
                            Thread.sleep(1000L);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                });
    
                Thread t2 = new Thread(() -> {
                    List<OOMObject>  refs = new ArrayList<>();
                    while (true){
                        OOMObject o1 = new OOMObject();
                        refs.add(o1);
                        System.out.println("thread-2申请1M");
                        try {
                            Thread.sleep(1000L);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                });
    
                t1.start();
                t2.start();
                i++;
            }
        }
    
        static class OOMObject {
            byte[] tempbytes = new byte[1024*1024];
        }
    
    }
    

    运行的结果如下:

    thread-1申请1M
    main thread
    thread-2申请1M
    thread-1申请1M
    main thread
    thread-2申请1M
    main thread
    thread-1申请1M
    thread-2申请1M
    main thread
    thread-1申请1M
    thread-2申请1M
    main thread
    。。。//省略一些
    Exception in thread "Thread-0" java.lang.OutOfMemoryError: Java heap space
        at com.example.demo.stream.OOMTest$OOMObject.<init>(OOMTest.java:56)
        at com.example.demo.stream.OOMTest.lambda$0(OOMTest.java:24)
        at com.example.demo.stream.OOMTest$$Lambda$1/1104106489.run(Unknown Source)
        at java.lang.Thread.run(Thread.java:748)
    //这里看到Thread-0线程OOM了,JVM会结束该线程并释放掉它所占用的内存(几乎是一半内存)。然后t2线程继续执行。
    
    thread-2申请1M
    main thread
    thread-2申请1M
    main thread
    thread-2申请1M
    main thread
    thread-2申请1M
    main thread
    。。。//省略一些
    Exception in thread "Thread-1" java.lang.OutOfMemoryError: Java heap space
        at com.example.demo.stream.OOMTest$OOMObject.<init>(OOMTest.java:56)
        at com.example.demo.stream.OOMTest.lambda$1(OOMTest.java:38)
        at com.example.demo.stream.OOMTest$$Lambda$2/812265671.run(Unknown Source)
        at java.lang.Thread.run(Thread.java:748)
    //这个时候t2线程也OOM了,JVM结束t2并释放它所占内存。并让主线程继续执行。
    main thread
    main thread
    main thread
    main thread
    main thread
    main thread
    main thread
    main thread
    

    上面从日志打印来验证的。我们来从JVM的gc看:


    image.png

    这个图执行的时间有点久,所以你可以看到最后main thread在执行的时候,old几乎为空。这个不用管,重点看下红色框框的内容。
    在第一个红色框,old满的之后,立即清理掉t1所占空间,以让t2继续执行。然后t2继续填满t1释放的内存后,它自己也OOM了。JVM释放t2所占内存,那就几乎是所有空间了。所以,main线程运行的时候old几乎为空。

    PS:查看上图的gc用jvisualvm,但是需要给它安装个插件Visual GC。

    安装插件文档:https://pan.baidu.com/s/19IeeGQnKcYEVpOqJtRsd_w,提取码:uzr1

    相关文章

      网友评论

          本文标题:JVM OOM异常会导致JVM退出吗?

          本文链接:https://www.haomeiwen.com/subject/pvlxohtx.html