OOM会不会导致JVM崩溃

3次阅读

共计 1929 个字符,预计需要花费 5 分钟才能阅读完成。

OOM 会不会导致 JVM 的 crash

前提

前几天有公司的大佬分享了一个产线问题:因为 VMThread 线程阻塞在进入安全点的位置,导致了 JVM 的 crash , 听完我才知道原来 JVM 的 crash 会产生一个 hs_err_pid 的 log 文件,本来以为自己已经熟知了 JVM 的知识,没想到还有新的知识点出现,然后我就想自己亲手模拟一下让 JVM crash 来产生这个 hs_err_pid log, 最后我选择了通过 OOM 来实现
但是我们都知道 OOM 只能导致回收掉当前线程,并不会导致 JVM crash , 所以我想都没想就写了下面的代码:

代码

import java.util.ArrayList;
import java.util.List;

public class MakeVmAbort {static List<Thread> ts = new ArrayList<>();

    static List<byte[]> bs = new ArrayList<>();

    public static void main(String[] args) {

        try {while (true) {Thread t = new Thread(() -> {while (true) {bs.add(new byte[1024 * 1024]);
                        try {Thread.sleep(500L);
                        } catch (InterruptedException e) {e.printStackTrace();
                        }
                    }
                });
                t.start();
                ts.add(t);
            }

        } catch (Exception e) {System.out.println(e.getStackTrace());
        }
    }

}
//java -Xmx50M -Xms50M -XX:ErrorFile=/home/wks/javacode/java_error.log  -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xloggc:/home/wks/javacode/gc.log

叉腰,不断的 new 线程,线程不断的产生 byte[],且专门有两个 static 的 list 来放 byte[] 和线程,保证不会被 GC 掉,这样 JVM 应该可以崩溃了吧。

过程

最后发现,JVM 确实会退出,但是并没有产生 hs_err_pid 的 log, 所以问题来了,JVM 是怎么退出的,是 linux kill 掉的吗?我用 egrep -i ‘java’ /var/log/messages 查了系统日志发现并没有,且我查看了 GC log 发现 JVM 一直处于 回收不到内存的状态。困惑了很久之后 我在 stackOverFlow 上提问:

https://stackoverflow.com/que…

大佬一下就点醒了我,JVM 最后的退出时因为 while 循环里 new Thread 都没有内存支持了,所以 main 线程都被回收了,而 JVM 的退出 是因为 当 JVM 中不存在 非 daemon 线程 所以主动关闭的。

此时映衬的我是多么的愚蠢,一个愚蠢的问题硬是搞了这么久。

那回到我的原始目的,怎么才能让 JVM 崩溃那,我最后暗搓搓的加了一个 XX:+ CrashOnOutOfMemoryError,才终于看到生成了 hs_err_pid

结论

所以 OOM 会导致 JVM 崩溃吗,答案是不会,JVM 会一直坚挺的运行,即使他已经报 GC overhead limit exceeded(预警 GC 回收的内存太少),那么什么样的错误会导致 JVM 的 crash 那?

我翻看了 oracle 的 Java troubleshoot 手册

https://docs.oracle.com/javas…

发现

A crash, or fatal error, causes a process to terminate abnormally. There are various possible reasons for a crash. For example, a crash can occur due to a bug in the Java HotSpot VM, in a system library, in a Java SE library or an API, in application native code, or even in the operating system (OS). External factors, such as resource exhaustion in the OS can also cause a crash.
Crashes caused by bugs in the Java HotSpot VM or in the Java SE library code are rare.

所以引起 crash 的原因大概是 JVM 的 gub, OS bug,OS 资源的回收。其实说了和没说一样,太笼统了。

好像写了一篇无聊的记录。。。

散会!!

正文完
 0