我该如何诊断和防止JVM崩溃?

当我遇到JVM崩溃时,我应该做什么(作为一个对JVM内部不了解的Java程序员)呢?

特别是,您将如何生成可重现的测试用例? 我应该在Sun(或IBM)的bug数据库中搜索什么? 我可以从生成的日志文件中获得哪些信息(例如hs_err_pidXYZ.log )?

如果崩溃只发生一台特定的机器,请运行memtest 。 我已经看到重复发生的JVM崩溃只有两次,在这两种情况下,罪魁祸首都是硬件问题,即RAM故障。

  1. 根据我的经验,它们几乎总是由使用JNI的本机代码引起的,无论是我的还是别人的。 如果可以,请尝试在没有本机代码的情况下重新运行,以查看是否可以重现它。

  2. 如果您的错误很容易重现,有时值得尝试关闭JIT编译器 。

  3. 正如其他人所指出的那样,有缺陷的硬件也可能导致这种情况,我已经在内存和video卡上看到过这种情况(当崩溃是在摇摆代码中时)。 尝试运行最适合您系统的硬件诊断。

  4. 由于JVM崩溃很少见,我会向Sun报告。 这可以在他们的bug数据库中完成 。 使用类别Java SE,子类别jvm_exact或jit。

  5. 在Unix / Linux下,您可能会获得Core转储。 在Windows下,JVM通常会告诉您它存储了已发生事件的日志。 这些文件经常给出一些提示,但从JVM到JVM会有所不同。 Sun 在其网站上提供了这些文件的完整详细信息。 或IBM可以使用IBM的alphaworks中的Java Core Analyzer和Java heapdump Analyzer来分析文件。

  6. 不幸的是,根据我的经验,Java调试器往往比受到帮助更有害。 但是,如果您熟悉读取C堆栈跟踪,则附加OS特定的调试器(例如Visual Studio)可能会有所帮助。

试图获得可重现的测试用例很难。 如果你有大量的代码总是(或几乎总是)崩溃,那么更容易,只是在它不断崩溃的同时慢慢移除部件,使结果尽可能小。 如果你根本没有可重复的测试代码,那就非常困难了。 我建议从上面的编号选择中获取提示。

Sun在此处记录了崩溃日志的详细信息。 如果你想进入肮脏的细节(这听起来像你没有), 这里还有一个很好的教程。

但是,正如评论者所提到的,JVM崩溃是一个非常罕见和严重的事件,在这种情况下调用Sun或IBM专业支持可能是值得的。

当iBM JVM崩溃时,它可能已经写入文件/tmp/dump_locations ,它会列出它编写的任何heapdump或javacore文件。

可以使用IBM的alphaworks中的Java Core Analyzer和Java heapdump Analyzer来分析这些文件。

Oracle网站上有一个很好的页面来解决这些类型的问题。

查看相关部分:

  • Hung进程 (例如jstack实用程序)
  • Post Mortem诊断