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资源的回收。 其实说了和没说一样,太笼统了。
好像写了一篇无聊的记录。。。
散会!!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。