核心目标是保现场、快取证、准定位:已配自动dump则直接取指定路径.hprof文件;未配但进程存活时用jmap -dump:live生成;docker中须确保-xx:heapdumppath为绝对路径、目录存在可写且挂载宿主机;oom后用docker cp导出,再用mat通过leak suspects和dominator tree精准定位泄漏点。

生产环境发生内存溢出(OOM)时,核心目标是:保现场、快取证、准定位。不能重启、不能删日志、更不能等服务彻底挂掉——关键在“进程还活着”这个时间窗口。
一、快速生成 Dump 的两种路径
分两种情况处理,取决于 JVM 启动时是否已配置自动 dump:
-
已配置自动 dump(推荐且最稳妥):检查启动参数中是否含
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/to/dumps/。若有,OOM 触发后 JVM 会自动生成 .hprof 文件,直接去指定路径找最新文件(注意按时间戳或 PID 区分,如oom_12345_1724876890.hprof)。 -
未配置但进程仍在运行:立即执行:
jmap -dump:live,format=b,file=/tmp/oom-$(date +%s).hprof <pid></pid>
其中<pid></pid>用jps -l或ps aux | grep java获取。加live参数可排除已标记为回收但尚未清理的对象,使 dump 更聚焦真实占用。
二、Docker 环境要特别注意落盘问题
容器内 dump 失败,90% 是因为路径不可写或未挂载。必须做到三点:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 启动参数中
-XX:HeapDumpPath必须用绝对路径,且带文件名模板,例如:-XX:HeapDumpPath=/data/dump/oom_%p_%t.hprof - Dockerfile 中提前创建目录并赋权:
RUN mkdir -p /data/dump && chown appuser:appuser /data/dump - 运行时通过
-v挂载宿主机目录:docker run -v /host/dumps:/data/dump ...,确保宿主机该路径有足够空间(dump 文件常达 2–10 GB)。
OOM 后,用 docker cp <container_id>:/data/dump/oom_*.hprof ./</container_id> 导出到本地分析。
三、用 MAT 高效定位泄漏点
拿到 .hprof 文件后,用 Eclipse Memory Analyzer(MAT)打开,重点看两个视图:
- Leak Suspects Report:一键扫描,自动标出最可疑的泄漏根因(比如某个 static HashMap 持有 5 万个对象);
- Dominator Tree:按 “Retained Heap” 降序排列,直接锁定吃内存最多的大户类及其引用链;
- 辅助验证:切换到 Histogram,筛选
java.lang.String、byte[]或业务实体类,看实例数和 retained 内存是否异常膨胀。
常见泄漏源头包括:静态集合未清理、ThreadLocal 没 remove、缓存无淘汰策略、监听器注册后未注销。
四、操作前务必做的三件事
- 立刻做流量切换或限流,避免新请求加剧堆压力,为 dump 和分析留出时间;
- 禁止
kill -9或滚动重启——除非服务完全不可用且已有降级预案; - 确认 OOM 类型(
Java heap space?Metaspace?GC overhead limit exceeded?),不同错误对应不同排查方向,别一上来就只盯堆。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










