android 内存泄漏分析

一、使用android studio profile分析

android studio 相比mat来说优势在于可以分析native内存的大小,例如Bitmap等,而mat不能分析native内存。

这里以android studio 3.42为例 ,方法如下

第一步、选择右上角profile app


第二步、选择 运行设备

第三步、点击中间的memory区域,让左上角出现dump 按钮

第四部、点击左上角区域的gc按钮,然后点击dump按钮

第五步、找出其中内存较大的实例或者对象较多的实例(这里选用bitamp)

简单说明一下这里的参数

Allocations: 表示这个类实例有多少个,实例越多占用的内存越大

Shallowsize:表示这个类仅仅自身占用的内存大小,不包含引用的对象和native的大小

NativeSize :表示这个对象native的内存大小

retainedsize:表示这个对象+引用对象+native对象的大小,分析内存泄漏时,可以从这里入手

另外:点击以上各个参数可以按照参数来进行排序

第六步,选择需要查看的对象

下面显示的是reference,上面显示的是对象的详细信息

depth表示引用链的深度,当对象比较多的时候,尤其是发现对象是被一个链表引用,可以通过,选择最浅的depth来找到节点

可以看到bitmap被一个linkedList$Node引用,为了找到父亲节点,需要找到,链表每往后一个节点,bitmap的引用深度就会+1,因此找深度最低的bitmap可以快速找到LinkedList节点

可以看到引用链为

二、使用ddms +mat分析

第一步、使用ddms抓取hprof 文件


使用由于mat是用来分析jvm标准的需要转换一下才能在mat上使用,此时使用sdk里的工具来转换

hprof-conv com.biluo.media.factory.hprof out1.hprof

第二步 选择直方图数据(Histogram)或者树状数据(Dominator Tree)

根据内存分布选择要分析引用链的对象,跟前文一样,这里依旧分析bitmap(由于mat无法分析native内存,无法拿到bitmap的真正大小,故此bitmap占用内存的比例以至于不能引起你的注意)

第三步 选择排除非强引用到gc节点的最短路径


第四部 得到结果

当最短引用是因为栈的引用导致,可能结果如下,有一个java local

总结

开源项目LeakCanary 的原理就是利用弱引用判断是是否观察的对象有没有被回收,弱没有被回收,则使用Debug.dumpHprofData(“文件名称”)来生成dump文件。然后得到引用链

android studio profile 拿到的内存信息比mat准确,但是android studio的分析手段没有mat多,有时候需要结合分析