堆转储是jvm在gc异常崩溃前捕获的内存快照,需主动配置:一、启用heapdumponoutofmemoryerror;二、监听hs_err日志触发补充分析;三、在高危阶段人工dump;四、避免jmap等失效操作。

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










