【问题标题】:How do I investigate the cause of a JVM crash?如何调查 JVM 崩溃的原因?
【发布时间】:2011-12-30 10:40:12
【问题描述】:

一天前,经过几个月的正常工作,我们的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

【问题讨论】:

标签: java crash jvm jvm-crash


【解决方案1】:

崩溃是在 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() 的代码可能会触发相同的崩溃

【讨论】:

  • 真的,很酷。但是其他服务器实例在不使用 yjp 的情况下崩溃。谢谢,我会在其他故障转储中检查请求的安全点。
  • 从其他崩溃请求线程:YJPAgent-Telemetry SocketAcceptorIoProcessor-0.0、AnonymousIoService-6、AnonymousIoService-14、AnonymousIoService-4、AnonymousIoService-7
  • @ubear 查看我的编辑。在没有 yourkit 分析器的情况下查看运行的崩溃日志会很有趣
  • 您可以在wuala.com/ubear/public 看到它。在其他崩溃中,调用了 RevokeBias。
  • @ubear 有趣,这是一个常见的崩溃。同样,我会尝试不使用 -XX VM 参数、-verbose:gc 和调试 VM 参数。
【解决方案2】:

我目睹的两次 JVM 反复崩溃都是由于硬件故障(即 RAM)造成的。运行memtest utility 是我尝试的第一件事。

【讨论】:

    【解决方案3】:

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

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

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

    【讨论】:

    • 我现在不明白为什么。我认为这是硬件问题或用户或内部数据处理中的任何问题。
    • @ubear:也尝试在没有 YourKit 代理的情况下运行。查看更新的答案。
    • 其他不使用 yjp 的服务器实例崩溃。
    • @ubear:从这些错误报告来看,YJP 显然不是罪魁祸首。我强烈建议您升级到最新的 JVM,看看崩溃是否继续发生。
    【解决方案4】:

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

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

    【讨论】:

    • 在另一台机器上工作正常。但我无法在其上重新创建相同的负载。
    【解决方案5】:

    切换到另一个版本的 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 没有崩溃了。

    【讨论】:

    • 我们在真正的硬件而不是 VPS 上运行我们的应用程序,因此,这个链接几乎不相关。谢谢。
    • 是的,你可能是对的。正如我所见,我们使用的是旧版本的内核 - 2.6.32-5-amd64,当我们在两年前经历那次崩溃时。感谢您的努力。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-13
    • 1970-01-01
    • 1970-01-01
    • 2015-02-18
    相关资源
    最近更新 更多