用LeakCanary和Eagle工具定位和分析内存泄漏问题
作者:李玲泉 2016-09-13 {{allComments.length}} 62482 干货分享在日常的开发、测试过程中,有时会遇到 OutOfMemoryError,Java堆溢出了,这表明程序有严重的问题,如果不解决此类问题,使用App过程中会因为内存占用过高而被系统强行收回堆空间,App异常退出,可见内存占用和内存泄漏问题十分影响用户的使用。因此我们需要找到造成OutOfMemoryError原因。一般有两种情况:
1、内存泄漏,对象已经死了,无法通过垃圾收集器进行自动回收,通过找出泄漏的代码位置和原因,以便确定解决方案;
2、内存溢出,内存中的对象都还必须存活着,这说明Java堆分配空间不足,检查堆设置大小,检查代码是否存在对象生命周期太长、持有状态时间过长的情况。
以上是处理Java堆问题的思路,具体是怎么进行分析,这里介绍如何使用LeakCanary工具和Eagle工具定位和分析内存泄漏的问题。
LeakCanary是一个检测内存泄漏的开源类库,Eagle工具是在Eclipse Memory Analyzer tool(MAT)工具上的二次开发,新增对比操作前后两个堆快照改变的对象数。
1.RefWatcher.watch() 创建一个 KeyedWeakReference 到要被监控的对象。
2.在后台线程检查引用是否被清除,如果没有,调用GC。
3.如果引用还是未被清除,把 heap 内存 dump 到 APP 对应的文件系统中的一个 .hprof 文件中。
4.在另外一个进程中的 HeapAnalyzerService 有一个 HeapAnalyzer 使用HAHA 解析这个文件。
5.通过唯一的reference key, HeapAnalyzer找到KeyedWeakReference,定位内存泄漏。
6.HeapAnalyzer计算到GC root的最短强引用路径,并确定是否是泄漏。如果是的话,建立导致泄漏的引用链。
7.引用链传递到APP进程中的 DisplayLeakService,并以通知的形式展示出来。
若非第一次安装MAT插件,先卸载MAT
安装经过二次开发后的MAT插件
1)进入help->install New Software->add
2)点击Archive,将xxx.zip选中,点击ok进行安装
3)待MAT工具安装完成重启eclipse
安装Eagle插件
4)将Eagle_xxx.jar放入eclipse的dropins目录,然后重启eclipse,即安装成功
验证是否安装成功操作如下,效果如下图
5)进入Memory Analysis打开一个hprof文件查看主菜单中是否有Eagle菜单项,以及对应的子菜单项Compare、Bitmap
6)打开Eclipse->Window->Show View->others中选择Eagle Views->Show Bitmap View
常规手工检查内存泄漏的操作是:
1)找到内存异常时的复现场景。
2)在内存泄漏开始时抓取一个hprof 文件,在内存泄漏很厉害时,app濒临崩溃时再抓取一个hprof 文件。
3)用Eagle工具的Compare功能, 对比看前后这两个dump的hprof文件,根据RetainedHeap项按照从大到小排序,就很容易看出来哪一块存在内存泄漏。有的时候能直接看出来多了一块,那么就从那一块入手进行分析,能比较快得到结果。
4)查找这个对象到 GC roots的最短强引用路径。
5)确定引用路径中的哪个引用是不该有的,然后对照代码修复问题。
推荐使用内存泄漏自动检测工具LeakCanary,步骤如下图:
分享一个结合LeakCanary和Eagle工具定位分析内存泄漏的实例:
LeakCanary定位发现的问题信息如下:
使用Eagle工具进一步分析的步骤:
1、初始状态获取堆快照start.hprof
2、至待测状态获取堆快照end.hprof
3、使用Ealge工具对比两个快照
(1)进入Memory Analysis,打开end.hprof->open query browser,选择Eagle->Compare
(2)-s选择初始快照start.hprof,-f选择类名过滤词,默认值为baidu
(3) 点击finish展示过滤结果表如下:
进一步详细分析是Context使用不当
修复前: 修复后:
将activity的context改为applicationContext,applicationContext生命周期更长,原因是引用了context导致activity结束的时候context不能释放,从而引发内存泄漏。
如果你看的意犹未尽,如果你想随时随地充实自己,请扫描以下二维码,关注我们的公众账号,可以获取更多技术类干货,还有精彩活动与你分享~