Android内存泄漏分析实例

来源:互联网 发布:mac部署maven环境变量 编辑:程序博客网 时间:2024/06/05 18:58

测试反馈contacts应用跑monkey 10H有内存泄漏嫌疑,通过procrank命令定时拍照得到USS和RSS的曲线图如下:
蓝色RSS,红色USS

monkey开始之后和结束时分别抓取了两个hprof,使用MAT解析出Leak Suspects,对比如下:

mokey开始时hprof的leak suspects饼状图

mokey结束时hprof的leak suspects饼状图

mokey开始时hprof的leak suspects的可疑点

mokey结束时hprof的leak suspects的可疑点

从对比图看到,mokey开始时hprof的leak suspects的可疑点有三个,mokey结束时hprof的leak suspects的可疑点有四个,两者种第一个可疑点都是2.9M的bitmap,因此这个不太可能时泄漏的地方,因此从第二个可疑点开始分析。
第二个可疑点也是bitmap,点击Details展开具体,如下:
这里写图片描述
可以看到疑点bitmap地址是0x32f63d90。
现在转到MAT,进入dominator_tree,对Retained Heap倒序排序,可以看到下图:
dominator_tree中对Retained Heap倒序显示
从图中看到第二行的bitmap地址就是第二个可疑点的bitmap的地址0x32f63d90,选中第二行,然后右键菜单选择list objects–>with incoming references,得到的结果中,再选中第一行,然后右键菜单选择path to GC roots–>execlude weak references,得到第二可疑点的调用关系:
第二可疑点的调用关系
从图中看到,0x32f63d90最终是被com.xxx.contacts.activities.ContactDetailActivity类所持有,为什么直接看activity类,因为activity时最容易被泄漏的。
现在再MAT中打开Histogram,查找com.xxx.contacts.activities.ContactDetailActivity类,如下图:
com.xxx.contacts.activities.ContactDetailActivity

可以看到这个类有2个objects,这就更值得可疑了,通常同一个activity不会同时两个,同样的,选中后右键菜单选择list objects–>with incoming references,得到两个ContactDetailActivity实例:
ContactDetailActivity实例

选中地址为0x3344a240的那行,右键菜单选择path to GC roots–>execlude weak references,得到ContactDetailActivity类到调用关系:
ContactDetailActivity类到调用关系

终于找到根源,com.xxx.contacts.sim.SimContactsOperation类持有ContactDetailActivity类实例,是被SimContactsOperation中的mContext引用。
现在看SimContactsOperation类源码,找到mContext,源码是这样的:

private static Context mContext;public SimContactsOperation(Context context) {        setContext(context);    }public static void setContext(Context context) {    mContext = context;}

原因找到了,ContactDetailActivity被静态变量mContext一直引用着,这会导致ContactDetailActivity无法回收的。
类似的,可以继续分析其他可疑点了。

1 0
原创粉丝点击