堆转储是JVM在GC异常崩溃前捕获的内存快照,需主动配置:一、启用HeapDumpOnOutOfMemoryError;二、监听hs_err日志触发补充分析;三、在高危阶段人工dump;四、避免jmap等失效操作。
堆转储(Heap Dump)本身不是“触发机制”,而是一种内存快照结果;所谓“在可达性分析彻底失败时留存第一现场”,实际指向的是:
当 JVM 的垃圾回收器(尤其是 G1、ZGC 等现代收集器)在执行可达性分析阶段遭遇严重异常(如 OOM during GC、SATB buffer overflow、标记栈溢出、并发标记崩溃等),导致 GC 中断或 JVM 挂起前,自动捕获堆状态以供事后根因分析
。
这并非 JVM 默认行为,需主动配置与协同设计。关键不在于“等它失败”,而在于
前置布防 + 异常捕获 + 快速落盘
。以下是实操要点:
一、启用 JVM 自动堆转储的兜底开关
当发生
(尤其是
或
)时,JVM 可自动生成
文件:
⚠️ 注意:该机制仅响应
抛出点,
不覆盖“可达性分析逻辑内部崩溃但未抛 OOM”的场景
(例如 C++ 层 mark-stack overflow 导致 VM 直接 abort)。
二、监控并拦截 GC 关键异常信号
部分致命 GC 异常(如 G1 的
崩溃、ZGC 的
)会触发 JVM fatal error 日志(
)。此时可借助:
:强制进程退出,确保
生效;
:绑定错误日志路径,便于脚本监听;
*
外部守护脚本轮询 `hserr
.log
# Internal Error
Concurrent Mark
SATB
mark stack overflow
jcmd
VM.native_memory summaryjstack` 补充上下文。
三、对高风险阶段做人工干预式快照
针对已知易出问题的场景(如大对象图首次并发标记、混合收集前全局标记完成点),可在应用层埋点:
使用
触发前检查
;
在关键业务入口/出口调用
(需
);
对于 Spring Boot 应用,可通过 Actuator
端点(生产环境需鉴权)手动触发。
四、规避“分析失败却无现场”的典型陷阱
❌ 不依赖
:进程卡死时该命令常超时或失败;
❌ 不在
或
中尝试 dump:此时对象已不可达,且线程可能被阻塞;
✅ 优先使用
+
对比原生内存突增;
✅ 配合
(JDK 11+)保留标记过程日志,定位分析中断位置。
不复杂但容易忽略。
OutOfMemoryErrorjava.lang.OutOfMemoryError: Java heap spaceMetaspace.hprof-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/path/to/dumps/
-XX:OnOutOfMemoryError="kill -3 %p" # 可选:同时 dump 线程栈OutOfMemoryErrorConcurrentMarkThreadmarking failedhs_err_pid*.log-XX:+ExitOnOutOfMemoryErrorHeapDumpOnOutOfMemoryError-XX:ErrorFile=/path/to/hs_err_%p.log**,一旦检测到+//等关键词,立即调用和ManagementFactory.getMemoryMXBean().gc()MemoryUsagecom.sun.management.HotSpotDiagnosticMXBean.dumpHeap(String outputPath, boolean live)--add-exports java.base/jdk.internal.vm=ALL-UNNAMED/actuator/heapdumpjmap -dump:live,format=b,file=heap.hprof finalize()Cleanerjcmd VM.native_memory baseline jcmd VM.native_memory summary -Xlog:gc*,gc+marking*,gc+heap*=debug