代码之家  ›  专栏  ›  技术社区  ›  Chathuranga Chandrasekara

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

  •  3
  • Chathuranga Chandrasekara  · 技术社区  · 15 年前

    我正在研究一个Java产品。客户机声称应用程序在任意时间后崩溃。由于这是一次事故,我们在日志中找不到任何信息。

    1. 是否有任何工具和方法来找出这些问题的原因?

    2. 我们能在代码方面做些什么来获得关于此类程序崩溃的更多信息吗?

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

    4. 有没有处理此类问题的已知程序?

    5. 如果你遇到这个问题,你会怎么处理?

    8 回复  |  直到 15 年前
        1
  •  4
  •   wds    15 年前

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

    除此之外,还有许多非标准选项可以通过它们来定义错误文件的位置等,请参见 Java HotSpot VM Options .

        2
  •  3
  •   ATorras    15 年前

    我会将您的应用程序日志调整到verboser级别,或者像前面所指出的那样调整JVM,但是如果您想要更多的选项,您可以尝试使用jvisualm来观察一些奇怪的东西(内存/线程/gc/jmx操作),最后,我会搜索 HSJEL 文件夹。 这些文件包含有关在硬盘崩溃时(内存冲突等)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
    
        3
  •  2
  •   Rich Seller    15 年前

    在崩溃之后,在崩溃过程中您没有日志,但是在实际崩溃之前您仍然拥有所有的日志。如果你的日志足够详细的话,这会给你很多信息。

    在爪哇,你把两个阶段结合起来:

    • 使用级别(致命、错误、警告、信息、调试),可以非常详细地登录代码。
    • 日志可以在生产中配置为只输出相关的内容(甚至与单个类的日志一样具体 debug 水平,而其余的只在 error 级别),以获得良好的性能和可接受大小的日志文件。

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

    1. 激活 错误 所有应用程序的级别,查看获得的内容
    2. 激活 warning 一个模块的级别,看看你得到了什么。
    3. 停用前一个,激活 info 一个包裹的等级,看看你得到了什么
    4. 停用前一个,激活 调试 一个班的水平,看看你能得到什么。
        4
  •  2
  •   dz.    15 年前

    首先,您应该知道,如果JVM崩溃或应用程序本身崩溃。如果JVM崩溃,Java进程在文件系统上创建多个崩溃转储,比如HSJEXXXX.PID。如果在Java开始的目录中找到这些文件中的一个,则应该在官方上检查此错误。 bug site 在阳光下。

    如果您的应用程序崩溃,您应该扩展日志基础结构(如前面提到的kle)。使用关机挂钩打印出来,关机(通常)也很方便。 here 供API参考。

        5
  •  2
  •   Michael Borgwardt    15 年前

    如果这个问题只发生在那个客户机上,询问他们是否在多台机器上运行应用程序。如果是的话,所有的问题都会发生吗?

    如果问题只发生在一台机器上,我会怀疑硬件有问题,很可能是RAM。这可以用类似的工具来诊断 memtest .

    我个人只看到了两个反复发生的JVM崩溃实例。在这两种情况下,问题都是RAM故障。

        6
  •  2
  •   Leigh    15 年前

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

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

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

        7
  •  1
  •   Joonas Pulakka    15 年前

    如果您使用的是JNI(或任何使用JNI的库),那么很容易使JVM崩溃,这样就不会留下任何痕迹。据我所知,调试此类问题的唯一方法是使用调试器逐步调试本机内容。

        8
  •  1
  •   Stephen C    15 年前

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