android内存泄漏的检测和排除

来源:转载



### 1、需要提前准备的两个工具,并完成配置
---
1. eclipse的MAT内存分析工具,它的独立安装版本下载地址如下:
> http://www.eclipse.org/mat/downloads.php
2. square的leakcanary库 https://github.com/square/leakcanary ,并参考readme配置。
### 2、如何知道是否发生内存泄漏
---
#### **leakcanary库发布之前**
> 为了评估应用是否发生内存泄漏,需要打开android studio的mermory monitor工具,一直玩耍需要测试的应用和手动触发gc,同时观察实时图例中的内存消耗情况。如果发现应用的内存一直处于增长状态,那么该应用有可能产生了内存泄漏。
dump文件格式转换
> hprof-conv dump.hprof converted-dump.hprof
#### **leakcanary库发布之后**
leakcanary库可以自动检测当前fragment或者activity有没发生泄漏,如果发生了内存泄漏,手机的通知栏会对用户进行通知,并提示简易的泄漏堆栈信息,同时,leak库还会在手机的download文件夹中生成dump文件,该文件记录了当前时刻应用详细的消耗的内存信息,包括存在的类对象,类对象数量等。该dump文件借助MAT内存分析工具即可分析造成内存泄漏的代码段。
下面举一个真实项目的例子。下图是在调试分享库时获取到的内存泄漏信息。
![image](/2014th7cj/d/file/p/20170703/labhde2wp1i.jpg)
从leakcanary的通知中可以得知,我们的SinaAssistActivity类发生了泄漏。我们从打开MAT工具,并用该工具打开dump文件。切换到OQL窗口,输入的查询命令可以获得所有在内存中的Activities。
```
select * from instanceof android.app.Activity
```
![image](/2014th7cj/d/file/p/20170703/gp2z2k2jvwy.png)
点击一个SinaAssistActivity对象,右键选中Path to GC roots。
![image](/2014th7cj/d/file/p/20170703/lgjsjivl4mu.png)
从上图可知,com.github.thinwonton.share.core.ui.SinaAssistActivity 被三个类持有,分别是KeyedWeakReference、SinaShareHandler和PhoneWindow$DecorView。其中,KeyedWeakReference是leakcanary库的,PhoneWindow$DecorView是安卓系统的窗口类,这两个类不需要理睬。真正造成内存泄漏的原因是,SinaShareHandler中的mWeiboShareAPI属性一直持有SinaAssistActivity对象,即时在SinaAssistActivity#onDestroy后还不释放。此时,我们回到SinaShareHandler类中需找原因,分析如下:
> SinaShareHandler中的mWeiboShareAPI属性是静态static的,我们在SinaShareHandler类的init初始化方法中给mWeiboShareAPI赋值,并令mWeiboShareAPI持有了SinaAssistActivity对象。但是,并没有在其它代码段中释放mWeiboShareAPI,由于static关键词使mWeiboShareAPI对象的生命周期持续到app结束,因此,SinaAssistActivity对象也没有得到及时释放。为了修复该bug,我们把SinaShareHandler类中mWeiboShareAPI对象声明为非static对象。

分享给朋友:
您可能感兴趣的文章:
随机阅读: