必须组合使用-XX:+HeapDumpOnOutOfMemoryError、-XX:HeapDumpPath和GC日志参数,确保路径可写、磁盘充足,并验证dump文件有效生成。

这个参数确实能帮你自动抓取 OOM 时的堆现场,但光加它还不够——它只管“保存”,不管“能不能保存成功”或“保存下来有没有用”。实际生产中,很多团队开了这个参数却依然查不出问题,原因往往出在配套配置没跟上。
必须配齐的三个关键参数
单独用 -XX:+HeapDumpOnOutOfMemoryError 容易失败或无效,建议组合使用:
- -XX:HeapDumpPath=/path/to/dumps/:指定 dump 文件存放目录,必须是应用进程有写权限的路径,且磁盘空间充足(建议预留 ≥2GB 空闲)
- -XX:+PrintGCDetails -Xloggc:/path/to/gc.log(JDK 8)或 -Xlog:gc*:file=/path/to/gc.log(JDK 9+):开启详细 GC 日志,和 dump 时间对齐后可还原 OOM 前内存变化趋势
- -XX:+HeapDumpBeforeFullGC(可选但推荐):在每次 Full GC 前也存一份 dump,有助于发现渐进式内存泄漏,不依赖 OOM 触发
注意路径与权限问题
常见失效场景不是参数写错,而是路径不可写:
- 容器环境(如 Kubernetes)中,
/tmp可能是内存文件系统(tmpfs),空间小且重启即丢;应挂载持久卷到明确路径,例如/data/dumps - Linux 下检查目标目录权限:
ls -ld /data/dumps && ps -o user= -p $PID,确保 Java 进程用户对该目录有写权限 - 避免使用相对路径或波浪号(
~/dumps),JVM 不解析 shell 展开,会直接创建名为~的目录
dump 文件太大?试试压缩和轮转
大堆(>4GB)生成的 hprof 文件可能达 10GB+,影响磁盘和后续分析。可配合以下策略:
- 用 -XX:+UseG1GC + -XX:G1HeapRegionSize=2M(视堆大小调整)提升 G1 回收效率,降低 dump 体积
- 启动时加 -XX:+UseCompressedOops(64 位 JVM 默认开启),减少对象指针占用,间接缩小 dump
- 用外部脚本做轮转:通过
find /data/dumps -name "*.hprof" -mtime +7 -delete定期清理旧 dump
验证是否真正生效
别等 OOM 才确认——主动触发一次测试:
- 写个简单接口,循环
new byte[1024 * 1024 * 100]分配大数组,快速耗尽堆 - 观察日志是否输出类似
java.lang.OutOfMemoryError: Java heap space,并检查目标目录是否生成.hprof文件 - 用
file /data/dumps/heap.hprof确认文件格式有效(应显示 “Java Heap Dump”)

















