直接用Eclipse MAT分析JVM堆快照的核心是:先看Leak Suspects报告快速定位可疑泄漏点,再结合Histogram(按类统计实例与内存)和Dominator Tree(按Retained Heap排序找内存支配者),最后通过Path to GC Roots回溯强引用链确认根因,并用多时间点快照对比验证是否持续增长。

直接用 Eclipse MAT 分析 JVM 堆快照,核心是“看住谁占得多、查清谁拽着不放、确认是不是真在涨”。不靠猜,靠三个视图联动 + 一条引用链回溯。
确保 dump 文件真实可用
没合格的 .hprof 文件,再强的工具也白搭:
- OOM 场景下,JVM 启动时加参数:
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/dumps/,并确认目录有写权限;生成的文件如java_pid12345.hprof大小应在几十 MB 以上(太小可能截断) - 非 OOM 场景,用
jmap -dump:live,format=b,file=heap.hprof <pid>手动抓取(注意:会触发 Full GC,生产环境避开高峰) - 打开前检查 MAT 内存配置:编辑
MemoryAnalyzer.ini,把-Xmx调到至少 4G(例如-Xmx4096m),否则大 dump 会解析失败或卡死
打开后先看 Leak Suspects 报告
这是 MAT 的第一道筛子,自动标出最可疑的泄漏点:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 启动 MAT → Open Heap Dump → 选中 .hprof 文件 → 弹窗默认选 “Keep default” → 等待分析完成
- 报告里出现 “Suspect 1”,比如提示 “One instance of ‘com.example.CacheManager’ is consuming 87% of heap”,点击 “Details” 查看完整引用路径
- 重点看它是否被 static 字段、ThreadLocal、监听器、未关闭的资源(如 InputStream)等意外强引用——这些才是泄漏的“锚点”
用 Histogram 和 Dominator Tree 定位大户
Leak Suspects 可能漏掉分散型泄漏,这时靠统计视图挖细节:
-
Histogram:按类列出实例数和内存占用。右键常见“吃内存大户”(如
byte[]、char[]、HashMap$Node、ArrayList)→ “Merge Shortest Paths to GC Roots” → 勾选 “exclude all phantom/weak/soft references”,只留强引用链 - Dominator Tree:按 Retained Heap 排序,找出真正“拖累全局”的对象。比如一个静态 Map 实例排第一,说明它及其所有 value 都无法回收,接着就去查这个 Map 的 key/value 生命周期
- 对比两者:Histogram 看“量多”,Dominator Tree 看“权重高”,合起来锁定关键类和典型实例
顺着 Path to GC Roots 追到底层代码
看到可疑对象只是开始,必须确认它为什么活到现在:
- 对目标对象(如某个超大的 ArrayList)右键 → “Path to GC Roots” → 选 “with all references”
- 典型路径示例:
MyService.INSTANCE → static cacheMap → HashMap$Node.value → ArrayList → elementData[],说明静态缓存没做淘汰或清理 - 若路径含
ThreadLocalMap,检查对应线程是否长期存活且未调用remove() - 若终点是
ClassLoader,警惕热部署、动态代理或 OSGi 导致类加载器泄漏,连带其加载的所有类实例都无法卸载
单次 dump 是快照,要确认泄漏得比对多个时间点的 dump:比如每 5 分钟抓一次,看某类实例数或 Retained Heap 是否持续上升。结合 jstat -gc

















