我该如何应对“程序崩溃”问题?

时间:2009-09-28 09:06:28

标签: java jvm crash

我正在开发Java产品。客户声称应用程序在任意时间后崩溃。如果发生崩溃,我们无法在日志中找到任何信息。

  1. 是否有任何工具,方法可以找出导致此类问题的原因?

  2. 我们可以在代码方面做任何事情来获取有关此类程序崩溃的更多信息吗?

  3. 我们可以为JVM启用“DEBUG”模式吗?如果是,我在哪里可以找到JVM日志文件/崩溃转储?

  4. 处理此类问题的任何已知程序?

  5. 如果您遇到此问题,您在解决此问题时的程序是什么?

8 个答案:

答案 0 :(得分:4)

我发现很难相信JVM在崩溃时没有输出。首先,仔细查看运行脚本,看看是否只是忽略输出。如果JVM由于未处理的异常而结束,它会将异常输出到stdout我相信。如果它崩溃(堆损坏等),它将向stderr输出一些东西。您的应用程序内日志记录很有用,但您应该记录任何输出到stdout和stderr的输出(您没有定义运行该应用程序的平台,但这基本上适用于所有这些)。

除此之外,您可以传递大量非标准选项来定义错误文件的位置等,请参阅Java HotSpot VM Options

答案 1 :(得分:3)

我会调整你的应用程序记录到verboser级别或调整JVM,如前所述,但如果你想要更多的选项,你可以尝试JVisualVM来观察一些奇怪的东西(内存/线程/ gc / jmx操作),并在最后机会,我会搜索 hs_err_pid * .log 文件。 这些文件包含有关硬崩溃时的JVM状态(内存违规等)的信息。 这里有一个例子:

#
# An unexpected error has been detected by HotSpot Virtual Machine:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x6d741e3a, pid=1572, tid=1364
#
# Java VM: Java HotSpot(TM) Client VM (1.5.0_11-b03 mixed mode)
# Problematic frame:
# V  [jvm.dll+0x1e3a]
#

---------------  T H R E A D  ---------------

Current thread (0x00a85c78):  VMThread [id=1364]

siginfo: ExceptionCode=0xc0000005, reading address 0x00000054

Registers:
EAX=0x00000050, EBX=0x00990000, ECX=0x0847b9f8, EDX=0x00000050
ESP=0x0ab0f660, EBP=0x0ab0f684, ESI=0x0847b9f8, EDI=0x0847b9f8
EIP=0x6d741e3a, EFLAGS=0x00010216

答案 2 :(得分:2)

崩溃后,您在崩溃期间没有日志,但在实际崩溃之前您仍然拥有所有日志。如果你的日志足够详细,那应该会给你很多信息。

在java中,您将两个阶段结合起来:

  • 登录代码可以非常详细,使用级别(致命,错误,警告,信息,调试)
  • 日志记录可以在生产中配置为仅输出相关内容(即使是debug级别的单个类的日志特定,而其余的仅在error级别),体面的性能和可接受大小的日志文件。

利用记录功能,您应该能够一点一点地缩小您的注意力。请注意,如果您的应用程序的日志太少,您应该尽快开始添加更多(当然,在适当的日志记录级别)。示例过程:

  1. 为所有应用程序激活error级别,看看你得到了什么
  2. 为一个模块激活warning级别,看看你得到了什么
  3. 停用上一个,激活一个包的info级别,看看你得到了什么
  4. 停用上一个,激活一个班级的debug级别,看看你得到了什么

答案 3 :(得分:2)

首先,您应该知道,如果JVM崩溃或您的应用程序本身。如果您的JVM崩溃,则java进程会在文件系统上创建多个故障转储,例如hs_errXXX.pid。如果您在java启动的目录中找到其中一个文件,则应在sun的官方bug site上检查此错误。

如果您的应用程序崩溃,您应该扩展您的日志基础结构(如提到的KLE)。使用关闭挂钩进行打印,关闭(通常)它也非常方便。请参阅here以获取API参考。

答案 4 :(得分:2)

如果只有该客户端出现此问题,请询问他们是否在多台计算机上运行该应用程序。如果是,那么问题是否都会发生?

如果只在一台机器上出现问题,我怀疑硬件有问题,很可能是RAM。这可以使用memtest等工具进行诊断。

我亲眼目睹了两次重复发生的JVM崩溃事件。在这两种情况下,问题都是RAM错误。

答案 5 :(得分:2)

有助于诊断内存问题的一些选项:

如果VM由于内存耗尽而退出,则JVM选项-XX:+HeapDumpOnOutOfMemoryError将创建堆转储。您可以使用eclipseMAT之类的东西来分析转储,以确定问题的原因。

同样-verbose:gc将提供详细的垃圾收集统计信息,添加-Xloggc:<file>会将此重定向到文件。

答案 6 :(得分:1)

如果您正在使用JNI(或任何使用JNI的库),则很容易使JVM崩溃,从而根本不会留下任何痕迹。据我所知,调试此类问题的唯一方法是使用调试器逐步完成本机操作。

答案 7 :(得分:1)

除了所有其他建议之外,请检查您的代码库是否有对System.exit()的调用。