堆转储(Heap Dump)分析
堆转储(Heap Dump)是 JVM 堆内存中所有对象的快照。通过分析堆转储,可以找出内存占用最大的对象、定位内存泄漏的根源。
本文将详细介绍堆转储的获取方式和分析方法。
堆转储方式
方式一:jmap 命令
方式二:JVM 参数
方式三:jcmd 命令
方式四:Arthas
堆转储文件分析
使用 MAT(Memory Analyzer Tool)
MAT 是 Eclipse 提供的专业堆转储分析工具:
MAT 核心功能
1. Leak Suspects 报告
MAT 自动分析可能的内存泄漏点:
2. Dominator Tree(支配树)
支配树显示对象之间的支配关系:
在支配树中,如果对象 A 支配对象 B,那么 A 被回收时 B 也必须被回收。
3. Histogram(直方图)
直方图显示各类对象的数量和内存占用:
关键指标
Shallow Heap
对象自身占用的内存,不包括引用的对象。
Retained Heap
对象自身及其直接/间接引用的对象占用的总内存。
分析实战
步骤一:打开堆转储
步骤二:查看 Leak Suspects
步骤三:查看 Histogram
步骤四:查看 Dominator Tree
步骤五:追踪 GC Roots
GC Roots 类型
堆转储中看到的 GC Roots 类型:
低内存堆转储优化
当堆内存很大时,堆转储文件可能非常大(数十 GB)。可以使用以下优化:
1. 只转储存活对象
2. 使用 HPROF 压缩格式
3. 远程转储
4. 增量转储
对于超大型堆,可以使用 MAT 的增量分析功能。
常见问题分析
问题一:HashMap 占用大量内存
解决:使用 WeakHashMap 或设置合理的缓存策略。
问题二:ClassLoader 泄漏
解决:确保 ClassLoader 不再使用时能被回收。
问题三:ThreadLocal 泄漏
解决:在 finally 块中调用 ThreadLocal.remove()。