Leakcanary原理使用解析

Getting Started

在build.gradle:

dependencies {
 debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.6.3'
 releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.6.3'
 // Optional, if you use support library fragments:
 debugImplementation 'com.squareup.leakcanary:leakcanary-support-fragment:1.6.3'
}

application

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 leakApplication = (MyApplication) context.getApplicationContext();
        return leakApplication.refWatcher;
    }
}

BaseActivity

public class BaseActivity extends Activity{
    @Override
    protected void onDestroy() {
        super.onDestroy();
        RefWatcher refWatcher =MyApplication.getRefWatcher(this);
        refWatcher.watch(this);
    }
}

更多用法

原理介绍

RefWatcher.watch() 会创建一个内存泄露的观察对象[KeyedWeakReference]。在后台进程中,会检查引用对象是否被清除或者触发回收,如果没有被清除或者回收,leaks讲相关引用存储在一个.hprof的文件内。
HeapAnalyzerService 运行在一个独立的process,HeapAnalyzer用HAHA框架[一个Android heap分析框架]解析堆栈。
由于一个唯一的引用键,HeapAnalyzer在堆转储中找到KeyedWeakReference,并找到泄漏的引用。
HeapAnalyzer 计算出内存泄露的链
结果通过 DisplayLeakService打印在APP进程中显示。

1.触发检测
每次当Activity/Fragment执行完onDestroy生命周期,LeakCanary就会获取到这个Activity/Fragment,然后初始化RefWatcher对它进行分析,查看是否存在内存泄漏。

2.判断分析是否内存泄露
首先尝试着从ReferenceQueue队列中获取待分析对象(软引用和弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用或弱引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个软引用或弱引用加入到与之关联的引用队列中),如果不为空,那么说明正在被系统回收,如果直接就返回DONE,说明已经被系统回收了,如果没有被系统回收,可能存在内存泄漏,手动触发系统GC,然后再尝试移除待分析对象,如果还存在,说明存在内存泄漏。

3.分析内存泄漏
确定有内存泄漏后,调用heapDumper.dumpHeap()生成.hprof文件目录。HAHA 是一个由 square 开源的 Android 堆分析库,分析 hprof 文件生成Snapshot对象。Snapshot用以查询对象的最短引用链。找到最短引用链后,定位问题,排查代码将会事半功倍。


image.png
image.png

如何解决内存泄露

为了解决内存泄露,你需要去看看使用或者引用是不是导致泄露,Leakcanary工具会抓到泄露并显示出来,可以根据相关代码检查是否内存泄露。
有相关问题可以在Stack Overflow 提问题。

总结

1.AOSP中也会存在内存泄露
2.LeakCanary对内存泄露检测有效,但是对于service泄露无法检测到

  1. 无法走到destory周期的内存泄露无法解决。
参考资料

1.leakcanary
2.性能优化工具(九)-LeakCanary
3.Leaks 原理解析

你可能感兴趣的:(Leakcanary原理使用解析)