APP内存优化:使用LeakCanary减少内存泄露

前言

看本篇文章之前,得首先了解下什么是内存泄露。还没接触过的朋友,建议先去了解一下。 https://www.jianshu.com/p/65f914e6a2f8

简而言之:
内存泄漏过多会导致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图标,即可查看到详细的内存泄露列表以及信息。

leaks
总结:

LeakCanary对于内存泄漏的检测非常有效,但也并不是所有的内存泄漏都能检测出来。

<1>无法检测出Service中的内存泄漏问题

<2>如果最底层的MainActivity一直未走onDestroy生命周期(它在Activity栈的最底层),无法检测出它的调用栈的内存泄漏。

所以说LeakCanary针对Activity/Fragment的内存泄漏检测非常好用,但是对于以上检测不到的情况,还得配合Android Monitor + MAT 来分析。

参考:
https://www.jianshu.com/p/70b8c87ea877
https://www.jianshu.com/p/6d6af494cd26
http://liuwangshu.cn/application/performance/ram-6-leakcanary.html
https://www.jianshu.com/p/3f1a1cc1e964

发布了70 篇原创文章 · 获赞 176 · 访问量 31万+

猜你喜欢

转载自blog.csdn.net/zheng_weichao/article/details/100557500