mat分析堆转储的核心是识别强占内存的对象及未回收原因,重点通过leak suspects报告快速筛查、dominator tree定位内存源头、histogram聚焦业务类异常增长。

用 MAT 分析堆转储文件,核心不是“打开”,而是“读懂内存里谁在强占空间、为什么没被回收”。重点看三类视图:Leak Suspects 报告快速筛出嫌疑对象,Dominator Tree 定位真正撑大堆的源头,Histogram 结合分组聚焦业务类异常增长。
先加载好 dump 文件
确保你有合法的 .hprof 文件——它通常由 JVM 参数 -XX:+HeapDumpOnOutOfMemoryError 自动触发,或用 jmap -dump:live,format=b,file=heap.hprof <pid></pid> 手动抓取(加 live 可排除已死对象,减小文件体积、提升分析效率)。启动 MAT 后直接 Open File 即可。若文件大于 2GB,需提前修改 MemoryAnalyzer.ini 中的 -Xmx(比如设为 -Xmx8g),否则会报 “Parsing heap dump” 错误。
从 Leak Suspects 报告入手
这是最省力的起点,MAT 自动扫描常见泄漏模式(如静态集合缓存、未关闭监听器、ThreadLocal 残留等):
- 报告顶部列出几个高风险嫌疑项,附带 Retained Heap 占比和引用链摘要
- 点 “Details” 查看完整路径,重点关注 “Shortest Paths to GC Roots” 中非虚引用(Class、Thread、JNI Global 等)构成的强持有链
- 如果报告为空,不代表没泄漏,只是不符合预设模式,需转入手动分析
用 Dominator Tree 找真正的大头
Dominator Tree 按支配关系组织对象:A 支配 B,意味着所有从 GC Root 到 B 的路径都必须经过 A。这能跳过中间容器,直达内存膨胀的根因:
- 按 “Retained Heap” 降序排列,排在前几行的对象(比如一个 HashMap 实例占 500MB)就是首要怀疑目标
- 右键该对象 → “Path to GC Roots” → 勾选 “exclude weak/soft/phantom references”,只看强引用链
- 注意区分:Shallow Heap 是对象自身大小,Retained Heap 是它独占且不可达的整个子图——后者才是泄漏影响的真实量级
靠 Histogram 锁定业务类异常
Histogram 按类统计实例数与总内存,适合发现数量暴增或单个类占用异常高的情况:
- 输入正则如
com.yourcompany.*快速过滤自定义包下的类 - 右键某一行 → “Merge Shortest Paths to GC Roots”,查清这批实例为何无法被回收
- 对比多个 dump(比如正常时段 vs OOM 前一刻),观察某类实例数是否持续不降反升——这是泄漏的典型信号
MAT 给出的是快照证据,不是代码结论。看到大量 ByteString 或 ArrayList,得回代码查 Protobuf 是否缓存了响应体、或静态 List 是否忘了清理。工具指方向,验证靠逻辑。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











