2.3 MAT
MAT(Memory Analyzer Tool),一个基于Eclipse的内存分析工具,是一个快速、功能丰富的Java heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗。
可以利用visualvm或者是 jmap命令生产堆文件在进行内存分析。
1. 用jmap生成堆信息
这样在E盘的jmap文件夹里会有一个map.bin的堆信息文件
2. 将堆信息导入到mat中分析
3. 生成分析报告
可以利用visualvm或者是 jmap命令生产堆文件,导入eclipse mat中生成分析报告:
1)Histogram(直方图)视图
- Class Name : 类名称,java类名
- Objects : 类的对象的数量,这个对象被创建了多少个
- Shallow Heap :一个对象内存的消耗大小,不包含对其他对象的引用
- Retained Heap :是shallow Heap的总和,也就是该对象被GC之后所能回收到内存的总和
通过直方图视图可以很容易找到占用内存最多的几个类(通过Retained Heap排序),还可以通过其他方式进行分组(见下图)。
如果存在内存溢出,时间久了溢出类的实例数量或者内存占比会越来越多,排名也越来越靠前。
图标进行对比,通过多次对比不同时间点下的直方图对比就很容易把溢出的类找出来。
2)支配树(Dominator Tree)
MAT提供了一个称为支配树(Dominator Tree)的对象图。支配树体现了对象实例间的支配关系,在此视图中列出了每个对象(Object Instance)与其引用关系的树状结构,同时包含了占用内存的大小和百分比。
通过Dominator Tree视图可以很容易的找出占用内存最多的几个对象(根据Retained Heap或Percentage排序),和Histogram类似,可以通过不同的方式进行分组显示:
Histogram视图和Dominator Tree视图的角度不同,前者是基于类的角度,后者是基于对象实例的角度,并且可以更方便的看出其引用关系。
以上只是一个初步的介绍,mat还有更强大的使用,比如对比堆内存,在生产环境中往往为了定位问题,每隔几分钟dump出一下内存快照,随后在对比不同时间的堆内存的变化来发现问题。
2.3.1 内存泄漏分析
开始排查
- 点击histogram ,在Class Name这一栏输入你要过滤的类名,回车
- 搜索类名的结果 ,发现这个类有13个对象 ,正常情况找个类只有一个对象,所以这个类泄漏了
MemoryLeak
- 继续查找是谁使用了这个类 ,一直持有这个类的对象,导致无法释放
第一步: 排除需引用
第二步:找到被谁持有
结果 - 找到泄漏原因
- 结果,发现是CallBackManager类中的sCallBack持有了MemoryLeakActivity的引用
- 既然找到了原因 ,自己就去查看代码吧
3 JVM内存泄漏分析步骤
造成OutOfMemoryError内存泄露典型原因:对象已经死了,无法通过垃圾收集器进行自动回收,需要通过找出泄露的代码位置和原因,才好确定解决方案。
- 用工具生成java应用程序的heap dump(如jmap)
- 使用Java heap分析工具(如MAT),找出内存占用超出预期的嫌疑对象
- 根据情况,分析嫌疑对象和其他对象的引用关系。
- 分析程序的源代码,找出嫌疑对象数量过多的原因。