jvm崩溃时生成的是os级core文件,非java堆转储;分析需用sa-jdi工具(仅jdk 8有效),依赖同版本带debug符号的jdk、gdb及正确配置,常用jstack -f -m或hsdb深度分析。

Java虚拟机(JVM)在发生严重错误(如崩溃、OOM、断言失败等)时,可生成核心转储(Core Dump)文件。Linux下JVM默认生成的是操作系统级core文件(如 core.12345),而非Java堆转储(heap dump)。要分析这类core文件,需借助JVM内置的 sa-jdi 工具——它是Serviceability Agent(SA)的Java调试接口实现,能从原生core中还原Java线程栈、堆对象、类信息等,无需目标JVM仍在运行。
确认JDK版本与SA支持状态
Serviceability Agent在较新JDK中默认禁用或受限:
- JDK 8u72+ 默认关闭SA;需启动JVM时显式启用:
-XX:+UnlockDiagnosticVMOptions -XX:+EnableDynamicAgentLoading(仅对部分场景有效) - JDK 9+ 移除了SA的默认支持,
sa-jdi.jar被废弃;OpenJDK 17+ 完全移除SA相关代码 -
实际可用前提:必须使用与生成core文件完全一致的JDK版本(包括更新号),且该JDK需含完整debug符号(推荐使用JDK的
debuginfo包或openjdk-debug发行版)
准备分析环境与依赖工具
仅靠sa-jdi无法直接解析原始core,需配合底层调试器协同工作:
- 安装对应架构的
gdb(如x86_64系统需gdb,非gdb-multiarch)并确保其能读取JDK的调试符号 - 将JDK的
lib/sa-jdi.jar加入classpath(JDK 8路径示例:$JAVA_HOME/lib/sa-jdi.jar) - 确保core文件与JVM二进制(
java可执行文件)匹配:用file core.xxx和file $(which java)核对架构与ABI;用readelf -n core.xxx | grep -A2 "NT_FILE"验证是否含内存映射信息
使用jstack(SA模式)快速查看Java线程栈
这是最常用且低门槛的入口方式,适用于JDK 8且core可识别场景:
- 命令格式:
jstack -J-d64 -F -m <jdk-path>/bin/java <core-file></core-file></jdk-path> -
-J-d64表示以64位模式运行jstack(多数现代JVM需此参数) -
-F强制模式(用于挂起的JVM或core分析);-m同时打印本地(C/C++)栈帧 - 若报错
sun.jvm.hotspot.debugger.DebuggerException: Can't attach to the process,说明SA未加载成功,需检查JDK debuginfo是否安装、core是否被截断、或尝试用sudo运行(因core访问常需权限)
通过HSDB图形界面深度分析(JDK 8专属)
hsdb 是SA提供的可视化调试器,适合深入排查类加载、对象引用链、内存布局问题:
- 启动方式:
java -cp "$JAVA_HOME/lib/sa-jdi.jar" sun.jvm.hotspot.HSDB - 菜单栏选择 File → Attach to Core…,指定core文件及对应
java二进制路径 - 成功后可浏览:Threads(Java线程状态与锁)、Classes(已加载类及实例数)、Oop Histogram(对象类型分布)、Inspector(选中对象查看字段值与引用)
- 注意:HSDB对GUI环境有依赖(需X11或macOS GUI),无界面服务器建议改用命令行工具或导出数据后离线分析
SA工具链能力强大但生态脆弱,当前主流实践中更推荐组合方案:用gdb + hotspot源码定位原生崩溃点,用jmap -dump(若JVM尚存活)或jcmd VM.native_memory summary辅助判断内存异常,再结合应用日志与GC日志交叉验证。对新项目,应优先启用-XX:+HeapDumpOnOutOfMemoryError和-XX:ErrorFile=...,降低对core dump分析的依赖。










