LeakCanary介绍
LeakCanary内存检测工具是由squar公司开源的著名项目。此项目主要用于内存检测。
开源鲜明的目录结构如下:
leakcanary |
|-leakcanary-analyzer
|-leakcanary-android
|-leakcanary-android-no-op
|-leakcanary-watcher
|-leakcanary-simple
leakcanary-android,leakcanary-android-no-op是针对android的检查封装。
leakcanary-analyzer:用于分析dump文件
leakcanary-watcher:用于监控内存泄露
leakcanary-android-no-op:空实现。用于release版本的依赖。
理论上这两个包完全可以应用到普通的java项目中,可以看出squar的工程师模块化分的特别清楚。
leakcanary-watcher主要提供抽象,核心的内存检测,执行流程,leakcanary-android负责具体的周边业务实现。
leakcanary-analyzer主要用作分析dump文件,由leakcanary-android去调用,结果再展示给开发者。
LeakCanary进程和线程
leakcanary在主进程进行内存检测,并且只在主线程空闲的时候执行,在单独的leakcanary进程进行内存分析。
实现原理
在Android开发中,主要用于检测Activity,Fragment等组件的内存泄露。对于Activity的内存检测,主要是检测当Activity执行了onDestory()之后是否还在内存中,如果一直在内存中,GC无法回收,那么代表内存泄露了,内存泄露的原因基本上都是有地方强引用了这个Activity对象。
无侵入获取需要检测的Activity
通过Application.registerActivityLifecycleCallbacks(),注册Application.ActivityLifecycleCallbacks回调,之后的所有Activity的生命周期都会回调这个接口,当然包括void onActivityDestroyed(Activity activity)方法。
如何判断对象泄露
获取了要检测的Activity对象后,怎么样才能判断这个对象就泄露了呢?
LeakCanary主要利用了WeakRefrence引用的对象,当GC回收了这个对象后,会被放进RefrecenQueue中。
LeakCanary先主动调用GC,然后检测这个对象是否在ReferenceQueue中,如果在,说明没有泄露,如果不在,说明有泄露的嫌疑,此处只是嫌疑,不一定真的泄露了。
为了方便检测继承WeakRefrence实现了KeydWeekRefrence,提供了一个唯一识别的Key,有利于对象检测,包括后面的Dump分析。
如何获取Dump文件
android已经提供好了获取Dump文件的Api:
android.os.Debug.dumpHprofData("dump文件名称");
如何分析Dump文件
analyzer借助haha分析Dump文件,计算出泄露对象的最短强引用路径。
以上就是LeakCanary的原理分析。
下面是分析源码过程中的类图和时序图(PS:都不标准,只方便理解用)