hs_err_pid文件中Compilation Events的含义及JVM崩溃相关分析
关于hs_err_pid文件里「Compilation events」章节的那些事儿
一、这个章节到底是干啥的?
简单说,这是JVM崩溃前记录的即时编译(JIT)事件日志。你知道JVM为了提速,会把频繁执行的热点代码从字节码编译成机器码对吧?这个章节就是按时间顺序,把崩溃前最后一批被JIT编译的方法信息记下来——比如你看到的computePath 0x00007f07d4434960,就是说这个computePath方法刚被编译成机器码,后面的十六进制数是这段机器码在内存里的起始地址。
二、崩溃方法同时出现在这儿,能说明啥?
这种情况大概率和JIT编译脱不了干系,主要有几种可能性:
- JIT编译器本身出bug了:比如JVM在编译
computePath这个方法的时候,编译器(不管是C1还是C2)自己出了问题——可能是编译逻辑触发了断言失败、内存访问异常,直接把JVM搞崩了。这种情况在一些旧版本JDK里偶尔会碰到,尤其是方法逻辑比较复杂或者用到了特殊语法的时候。 - 刚生成的机器码有问题:这个方法刚被编译完,生成的机器码存在缺陷(比如寄存器用错了、内存越界),刚执行就触发了崩溃。这时候堆栈跟踪里的崩溃地址,正好和Compilation events里记录的机器码起始地址对上,就很能说明问题。
- JIT优化把代码改坏了:极端情况下,JIT的优化逻辑跑偏了,把原方法的字节码逻辑改得和预期不一致,执行时出现了不可预料的错误(比如空指针、数组越界),进而导致JVM崩溃。
给你个排查小思路
如果要验证是不是JIT的锅,可以试试这俩办法:
- 加JVM参数
-Xint,强制JVM用解释执行模式(不做JIT编译),如果崩溃不再出现,那基本实锤是JIT的问题。 - 针对这个方法禁用JIT编译,加参数
-XX:CompileCommand=exclude,你的包路径/你的类名.computePath,先临时规避问题,之后再考虑升级JDK版本(毕竟很多JIT的bug在新版本里都修复了)。
内容的提问来源于stack exchange,提问作者Assimiz
相关产品推荐
相关产品推荐

