LeakCanary 检测内存泄漏

使用

  1. module 下的 dependencies 中添加依赖
dependencies {
    debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3'
    releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3'
}
  1. Application 中初始化
public class App extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        LeakCanary.install(this);
    }
}

两步就成功集成了,当出现内存泄漏时会提示

In com.renxl.leakcanarydemo:1.0:1. * com.renxl.leakcanarydemo.SecondActivity has leaked: 

* GC ROOT static com.renxl.leakcanarydemo.Single.view  // 发生泄漏的根源
* references android.view.View.mContext  // 发生泄漏的对象
* leaks com.renxl.leakcanarydemo.SecondActivity instance  // 发现泄漏的对象的实例
* Reference Key: 0491c0f8-6706-4ee8-926d-fcbc91f06717 
* Device: Meizu Meizu m3 note m3note 
* Android Version: 5.1 API: 22 * Durations: watch=5020ms, gc=131ms, heap dump=6026ms, analysis=120163ms

手机通知栏也会提示

``
GC ROOT static Single.view
references View.mContext 
leaks SecondActivity instance
``

可以快速的定位内存泄漏的位置

原理

  1. Application 中初始化 LeakCanary 时得到 RefWatcher 对象用于监控那些本该被回收的对象,同时启用一个 ActivityRefWathcer,用于自动检测 Activity.onDestory 之后发生泄漏的 activity
  2. 在 onDestory 中调用 RefWatcher.watch() 方法,该方法会创建一个 KeyedWeakReference 到要被监控的对象
  3. 在后台线程检查引用是否被清除,如果没有,调用 GC
  4. 如果引用还未清除,把 heap 内存 dump 到 APP 对应的文件系统中的 .hprof 文件
  5. 另一进程中的 HeapAnalyzerService 有一个 HeapAnalyzer 来解析这个文件
  6. 通过唯一的 refrence key ,HeapAnalyzer 找到 KeyedWeakRefrence ,定位内存泄漏
  7. HeapAnalyzer 计算到 GC roots 的最短强引用路径,并确定是否是泄漏,如果是,建立导致泄漏的引用链
  8. 引用链传递到 APP 进程中的 DisplayLeadService,并以通知形式展示出来。

进阶

上传 lead trace 到服务器

  1. 我们可以自定义 LeakService 继承 DisplayLeakService ,在有内存泄漏时,将泄漏信息传递至服务器

  2. 注册 LeakService

  3. 在初始化 LeakCanary 时使用我们自定义的 LeakService

你可能感兴趣的:(LeakCanary 检测内存泄漏)