当前位置:Java -> 探索Java的‘hs_err_pid’文件

探索Java的‘hs_err_pid’文件

你是否曾经想过当Java虚拟机(JVM)遇到严重错误并意外崩溃时会发生什么?嗯,那时JVM会生成一个神秘的文件,名为“hs_err_pid”。在这篇文章中,我们将揭开这个文件的谜团。我们将深入探讨它的目的,学习如何解读它的内容,并探索在Java应用程序出现问题时它提供的重要信息。因此,如果你曾经对“hs_err_pid”文件感到困惑,或者只是对如何理解它感到好奇,继续阅读以发现你需要的关键见解。

什么是“hs_err_pid”文件?

当Java虚拟机(JVM)遇到严重错误并崩溃时,它会留下一系列面包屑,形成一个名为“hs_err_pid”的文件。这个文件是包含各种级别细节的信息宝库,如线程、库、应用程序、资源、环境和系统。它作为JVM在崩溃时刻状态的全面报告。这些细节对于诊断崩溃的原因非常有价值。

hs_err_pid”文件创建在哪里?

当JVM崩溃时,“hs_err_pid”文件的位置如下确定:

  1. -XX:ErrorFile: 如果JVM参数指定了“-XX:ErrorFile”,“hs_err_pid”文件将被创建在这个参数指定的路径中。
  2. 工作目录: 在没有使用“-XX:ErrorFile”参数的情况下,JVM会在Java应用程序的工作目录中生成“hs_err_pid”文件。
  3. 临时目录: 如果由于空间不足、权限问题或其他限制等原因,文件无法在工作目录中创建,JVM会在操作系统指定的临时目录中创建“hs_err_pid”文件。

如何读取“hs_err_pid”文件?

hs_err_pid”文件是一个纯文本文档,虽然可以通过标准文本编辑器打开并检查它的内容,但由于其技术性质,对文件内部的原始数据进行解读可能是一项具有挑战性的任务。在许多情况下,解读原始格式的文件可能会非常复杂和耗时。

为了简化这一过程并使信息更易于访问,许多开发人员选择使用专门的工具,如fastThread。该工具被设计用于解析“hs_err_pid”文件,并以更易读和组织的格式呈现数据,包括图表和指标。

如何分析“hs_err_pid”文件?

Fig: 用于分析hs_err_pid文件的fastThread工具

图:fastThread工具用于分析“hs_err_pid”文件

您可以使用fastThread工具分析“hs_err_pid”文件。

  1. 登录fastThread
  2. 上传hs_err_pid文件
  3. 单击“分析”按钮

完成这些步骤后,fastThread将立即生成一份全面的报告。该报告旨在为您提供丰富的信息,包括多个部分,将帮助您深入了解JVM问题。继续阅读本文以了解这些部分。

JVM信息

Fig: JVM版本信息

图: JVM版本信息

报告的第一部分致力于提供关于Java虚拟机(JVM)的重要细节。它包括:

  • JRE版本: 此部分显示了JVM崩溃时所使用的Java运行时环境(JRE)版本。
  • 崩溃时间: 您将找到JVM遇到严重错误并崩溃的精确日期和时间。
  • 经过时间: 这个宝贵的度量指示了JVM崩溃发生前的运行时间。

崩溃原因

Fig: 导致JVM崩溃的高级原因

图: JVM崩溃的高级原因

在这一部分,您将找到导致JVM崩溃的高级原因。常见的崩溃原因包括:

  • SIGSEGV
  • SIGBUS
  • EXCEPTION_ACCESS_VIOLATION
  • EXCEPTION_STACK_OVERFLOW
  • 内存不足错误

关于这些原因的解释,您可以参考Oracle文档

堆大小

图:JVM内存区域利用情况

图:JVM内存区域利用情况

该部分提供了JVM内存区域的分配和使用情况的详细说明:

  1. 年轻代
  2. 老年代
  3. 元空间

了解这些内存区域的分配和使用大小对于诊断与内存消耗相关的问题至关重要。在内存泄漏的情况下,您可能会观察到使用大小接近其最大容量。

执行的代码/库

在此部分,您将找到JVM在崩溃发生时正在执行的确切代码行或库。以下是一些示例:

代码行

  • # J 11538 C2 com.buggyapp.StoryContentPushProcessor.scribeUpsert(Lcom/espn/cricket/data/domain/StoryType;Ljava/nio/file/Path;)V (224 bytes) @ 0x0000000002629d49 [0x0000000002626ce0+0x3069]
  • # J 17883 c2 java.util.concurrent.ConcurrentSkipListMap.doPut(Ljava/lang/Object;Ljava/lang/Object;Z)Ljava/lang/Object; java.base@10.0.2 (548 bytes) @ 0x00007fe0bd97e957 [0x00007fe0bd97b740+0x0000000000003217]

  • [jvm.dll+0x374bae]
  • [libCSTBk5.so+0x43949]

活跃线程

图:JVM崩溃时运行的活跃线程的堆栈跟踪

图:JVM崩溃时运行的活跃线程的堆栈跟踪

这个部分可能是报告中最重要的部分,因为它揭示了在JVM崩溃的确切时刻正在活跃执行的线程,以及其相应的堆栈跟踪。在许多情况下,崩溃时活跃执行的线程是识别根本原因的关键焦点。

在上面的示例中,您可以注意到线程正在处理‘com.sap.conn.rfc.driver包。这个包存在于SAP驱动程序库中。显然,这个应用程序在旧版本的SAP驱动程序上运行,而这个版本已知存在bug。因此,这个应用程序崩溃了。一旦SAP驱动程序升级,应用程序内的JVM崩溃问题便停止了。

核心转储位置

在JVM崩溃时,可能会生成核心转储。该部分通知您这些核心转储写入的特定文件路径。

所有线程

图:JVM崩溃时运行在JVM中的所有线程

图:JVM崩溃时运行在JVM中的所有线程

该部分提供了在JVM崩溃时JVM内的线程的信息。其中包括线程数、名称、状态和类型的详细信息。JVM中的线程数量可能是一个需要考虑的关键因素,在提供的示例中,有1464个线程,这对于所讨论的应用程序来说是显著高的。

线程的名称通常提供有价值的线索,关于它们的来源或与特定线程池的关联。例如,在此示例中,您可以观察到有超过一千个线程来自‘I/O dispatcher’线程池。了解线程情况对于诊断Java应用程序中的性能和并发问题是有帮助的。

JVM参数

图:应用程序启动时的JVM参数

图:应用程序启动时的JVM参数

该部分揭示了您的应用程序启动时的系统属性(即‘D’)和JVM参数(即‘-X’和‘-XX:’)。

环境变量

Fig: 设备的环境变量

 Fig: 设备的环境变量

本部分包含在JVM启动时生效的环境变量的全面列表。这些变量可以包括关键元素,如'PATH'、'SHELL'、'JAVA_HOME'、'CLASSPATH'等。了解环境变量对于评估Java应用程序运行的上下文至关重要。

动态库

本部分提供了Java应用程序启动时相关的所有库和依赖项的完整列表,包括应用程序库、第三方库、框架和本地库。清单包括各种组件,例如动态库(.dll)、共享对象(.so)和Java归档文件(*.jar)。

系统

Fig: 系统级别细节

 Fig: 系统级别细节

该部分提供了关于您的应用程序的系统级别细节:

  • 操作系统:它提供了关于您的应用程序运行的操作系统的详细信息。
  • 内存:本部分涵盖了执行应用程序的设备的内存配置。还报告了崩溃时的内存利用率,为资源消耗提供了洞察。
  • CPU:您将找到有关执行应用程序的设备的CPU配置的信息,这对于评估性能和兼容性至关重要。
  • JVM版本:报告的这部分显示了正在使用的JVM版本,这对于兼容性和调试至关重要。

事件信息

报告的事件信息部分包含以下子节:

  • 内部异常:报告了JVM中抛出的最近异常。
  • 去优化事件:有时,JVM将已编译(或更优化)的堆栈帧转换为解释(或不太优化)的堆栈帧。例如:编译器最初假定引用值永远不会为null,并使用陷阱内存访问进行测试。随后,应用程序使用了null值,方法被去优化并重新编译以使用显式的测试和分支习语来检测这样的null。最近的这种去优化事件在本部分报告。
  • 类重定义:报告了最近重新定义的类。有时,类会被APM代理和其他代理技术重新定义。
  • 编译事件:显示了最近从Java字节码编译为本机代码的方法。

结论

在Java的‘hs_err_pid’文件中探索过程中,我们深入研究了一种宝贵的信息源,可以成为诊断JVM崩溃的关键。通过解码‘hs_err_pid’文件,您可以将错误消息转化为可操作的见解,使故障排除变得比必要的更加顺畅。

推荐阅读: 31.HashMap、ConcurrentHashMap及Hashtable的区别

本文链接: 探索Java的‘hs_err_pid’文件