精准抓现场需用jmap -dump:live获取gc后存活对象,mat分析按leak suspects→histogram→dominator tree顺序聚焦定位,辅以多dump对比和jmap -histo:live快速筛查。

关键在“精准抓现场”和“聚焦分析路径”,不是 dump 越多越好,也不是视图点得越全越准。
一、生产环境必须用 live 参数生成有效快照
直接执行 jmap -dump:format=b,file=heap.hprof
正确命令是:
-
jmap -dump:live,format=b,file=heap.hprof
:强制只保留 GC 后仍存活的对象,这才是真实内存占用 - 若进程响应迟缓,加 -F 强制执行:jmap -F -dump:live,format=b,file=heap.hprof
(注意会引发短暂 STW) - 执行前务必确认:jps -l 核对 PID,df -h 检查目标路径剩余空间(至少预留比堆内存大 20% 的空间)
- 留意权限问题:目标目录需对运行 jmap 的用户可写,否则命令静默失败,生成的 .hprof 文件可能只有几 MB
二、MAT 启动前必须调大内存配置
MAT 默认启动内存(-Xmx1g 或 2g)远低于实际 dump 文件大小。4GB 的 heap.hprof,MAT 启动时卡在 “Loading…” 或直接闪退,基本就是这个原因。
操作步骤:
- 打开 MemoryAnalyzer.ini,找到 -Xmx 行
- 改为至少为 dump 文件大小的 1.5 倍(例如 4GB dump → 设为 -Xmx6g)
- 确保运行 MAT 的 JDK 版本 ≥ 11(MAT 1.14+ 不兼容 JDK 8)
- 避免使用 Eclipse 插件版 MAT:它受限于 Eclipse 自身 JVM 配置,极易 OOM
三、三个核心视图,按顺序高效排查
不要一上来就展开千层引用链。真正高效的路径很窄:
- Leak Suspects Report:MAT 自动生成的摘要页,通常第一项就是最大嫌疑点(例如:“One instance of ‘com.example.CacheManager’ is holding 3.2 GB”)。这是最省力的入口,90% 的典型泄漏能在这里直接定位到类或单例实例
- Histogram:按类统计实例数与 retained heap。重点关注 retained heap 排名靠前、且实例数明显异常(比如某 UserSession 类有 80 万实例,而日常峰值应 ≤ 5000)
- Dominator Tree:在 Histogram 中右键可疑类 → “Merge Shortest Paths to GC Roots” 或直接打开 Dominator Tree,看谁在“支配”这些对象。重点观察 “Retained Heap” 列,找顶部几个超大节点及其直接引用者(如静态 Map、未关闭的监听器、线程局部变量)
四、辅助手段提升定位效率
除了主流程,这些做法能减少误判、加快闭环:
- 线上服务建议提前配置:-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/dump/,OOM 发生时自动保存最真实的现场
- 对比多个时间点的 dump:比如凌晨低峰期 vs 白天高峰后,用 MAT 的 “Compare Basket” 功能查看哪些类的实例数/retained heap 增长最显著
- 结合 jmap -histo:live
快速筛查:输出中关注 “bytes” 列排名靠前、且与业务逻辑无关的类(如大量未释放的 byte[]、ArrayList、HashMap.Entry) - 警惕常见泄漏源:静态集合缓存、未注销的事件监听器、ThreadLocal 持有业务对象、未关闭的流或连接池资源











