简而言之:
内存泄漏过多会导致OOM,从而使APP崩溃。因此内存泄露向来都是内存优化的重点。避免、发现和解决内存泄漏是APP优化中尤为重要的一环。
本文即为介绍通过LeakCanary发现和解决内存泄露。
一、简介
LeakCanary是一个可视化的内存泄露分析工具,由Square公司基于MAT开源。与其他内存检测工具相比,LeakCanary学习成本低,易于发现问题,十分适合刚接触内存优化的同学学习。
但需要注意的是,LeakCanary并不能检测出来所有的内存泄漏,因此想深度优化的话,还需要配合其它工具一起使用,本文先略此不表。
二、使用
1、 首先需要读写权限,因为LeakCanary需要生成hprof文件,保存在SD卡里面,因此需要先申请权限
<!– SDCard中创建与删除文件权限 –>
<uses-permission android:name=“android.permission.MOUNT_UNMOUNT_FILESYSTEMS”/>
<!– 向SDCard写入数据权限 –>
<uses-permission android:name=“android.permission.WRITE_EXTERNAL_STORAGE”/>
2、在app build.gradle 中加入引用:
dependencies {
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'
testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'
}
3、在 Application 中:
简单使用
如果要求比较低,只需要能够检测Activity的内存泄漏,代码如下:
//检测Activity的内存泄漏
public class MyApplication extends Application {
@Override public void onCreate() {
super.onCreate();
if (LeakCanary.isInAnalyzerProcess(this)) {
// This process is dedicated to LeakCanary for heap analysis.
// You should not init your app in this process.
return;
}
LeakCanary.install(this);
}
}
如果当前的进程是用来给LeakCanary 进行堆分析的则return,否则会执行LeakCanary的install方法。这样我们就可以使用LeakCanary了,如果检测到某个Activity 有内存泄露,LeakCanary 就会给出提示。
高级使用
如果除了Activity的内存泄漏,还需要检测其他类的内存泄漏,那么可以使用RefWatcher来进行监控。代码如下所示:
public class MyApplication extends Application {
private RefWatcher refWatcher;
@Override
public void onCreate() {
super.onCreate();
refWatcher= setupLeakCanary();
}
private RefWatcher setupLeakCanary() {
if (LeakCanary.isInAnalyzerProcess(this)) {
return RefWatcher.DISABLED;
}
return LeakCanary.install(this);
}
public static RefWatcher getRefWatcher(Context context) {
MyApplication myApplication = (MyApplication) context.getApplicationContext();
return myApplication.refWatcher;
}
}
install方法会返回RefWatcher用来监控对象,Application中还要提供getRefWatcher静态方法来返回全局RefWatcher。
然后,需要关注拿个页面,就重写对应页面的onDestory()方法,加上如下代码:
RefWatcher refWatcher = MyApplication.getRefWatcher(this);
refWatcher.watch(this);
4、运行
像往常一样运行程序后,会在界面生成一个名为Leaks的应用图标。接下来去执行APP的操作,如果发生了内存泄露,就会闪出一个提示框,提示“Dumping memory app will freeze.Brrrr.”,Notification也会有显示,这时点击桌面的Leaks图标,即可查看到详细的内存泄露列表以及信息。
总结:
LeakCanary对于内存泄漏的检测非常有效,但也并不是所有的内存泄漏都能检测出来。
<1>无法检测出Service中的内存泄漏问题
<2>如果最底层的MainActivity一直未走onDestroy生命周期(它在Activity栈的最底层),无法检测出它的调用栈的内存泄漏。
所以说LeakCanary针对Activity/Fragment的内存泄漏检测非常好用,但是对于以上检测不到的情况,还得配合Android Monitor + MAT 来分析。