如何调查JVM崩溃的原因?

一天前,经过几个月的正常工作,我们的java应用程序偶尔会崩溃并出现以下错误:

# # A fatal error has been detected by the Java Runtime Environment: # # Internal Error (safepoint.cpp:247), pid=2075, tid=140042095163136 # guarantee(PageArmed == 0) failed: invariant # # JRE version: 6.0_23-b05 # Java VM: Java HotSpot(TM) 64-Bit Server VM (19.0-b09 mixed mode linux-amd64 compressed oops) # An error report file with more information is saved as: # /var/chat/jSocketer/build/hs_err_pid2075.log # # If you would like to submit a bug report, please visit: # http://java.sun.com/webapps/bugreport/crash.jsp # 

我查看了hs_err_pid2075.log,看到有一个活动线程处理网络通信。 但是,在过去几个月中没有进行任何应用程序或环境更改。 也没有任何负载增长。 我该怎么做才能理解,崩溃的原因是什么? 是否有任何常见的步骤来调查jvm崩溃?

UPD http://www.wuala.com/ubear/public

崩溃发生在JVM中,而不是外部本机代码中。 但是,它崩溃的操作是由外部DLL启动的。

hs_err_pid文件中的这一行解释了崩溃的操作:

 VM_Operation (0x00007f5e16e35450): GetAllStackTraces, mode: safepoint, requested by thread 0x0000000040796000 

现在,线程0x0000000040796000是

 0x0000000040796000 JavaThread "YJPAgent-Telemetry" daemon [_thread_blocked, id=2115, stack(0x00007f5e16d36000,0x00007f5e16e37000)] 

这是由Yourkit创建的一个线程。 “GetAllStackTraces”是探查器为了进行采样而需要调用的东西。 如果删除分析器,则不会发生崩溃。

使用此信息无法说明导致崩溃的原因,但您可以尝试以下操作:删除所有-XX VM参数,-verbose:gc和调试VM参数。 它们可能会干扰JVM的分析界面。

更新

调用java.lang.Thread#getAllStackTraces()java.lang.Thread#getStackTrace()可能会触发相同的崩溃

我目睹两次重复发生的JVM崩溃都是由于硬件故障,即RAM造成的。 运行memtest实用程序是我尝试的第一件事。

我可以从错误报告中看到你已经加载了YourKit代理。 它的遥测线程被称为似乎失败的操作的请求者。 尝试在没有YJP代理的情况下运行应用程序,看看是否仍然可以重现崩溃。

通常,JVM崩溃很难诊断。 它们可能由于某些JNI代码或JRE本身中的错误而发生。 如果您怀疑后者,可能值得向Oracle提交错误报告。

无论哪种方式,我建议升级到最新版本的Java 6 ,以确保它不是已经修复的已知问题。 在撰写本文时,当前版本是Java 6更新29。

如果你没有搞乱任何直接导致这种情况的东西(这基本上意味着使用调用本机代码的本机代码或库),那么它几乎总是归结为JVM或硬件问题中的错误。

如果它运行良好多年并且现在已经开始崩溃,那么在我看来,硬件问题最有可能是两者。 你可以在另一台机器上运行它来排除这个问题吗? 当然,升级到最新的Java更新肯定也不会有什么坏处。

切换到另一个版本的linux-kernel“修复”了JVM压溃问题( http://forum.proxmox.com/threads/6998-Best-strategy-to-handle-strange-JVM-errors-inside-VPS?p= 40286#post40286 )。 它帮助我使用真正的服务器。 上面有Ubuntu服务器10.04 LTS OS,内核为2.6.32-33版本。 所以内核更新解决了这个问题。 JVM不再崩溃了。