LeakCanary工作原理解析

简介

 LeakCanary是一款开源的内存泄露检测工具,可以用来检测项目中的Activity是否能够被GC及时回收。

使用方式

在项目的build.gradle文件添加:

dependencies {

     debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.3'

     releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.3'

}

然后在Application中调用install方法:

public class MyApplication extends Application {

      @Override

      public void onCreate() {

            super.onCreate();

            LeakCanary.install(this);

      }

}

LeakCanary.install()方法大致流程:

LeakCanary.install() -->  创建RefWatcher --> 创建ActivityRefWatcher --> watchActivities() --> 注册Activity生命周期回调

当生命周期回调onActivityDestroyed的时候,触发ActivityRefWatcher的onActivityDestroyed调用:

ActivityRefWatcher.onActivityDestroyed() --> RefWatcher.watch() --> 在watch方法内部,通过关注的activity的引用、随机生成的key值、一个引用队列ReferenceQueue,  来构建一个KeyedWeakReference 弱引用对象。同时,将key加入retainedKeys集合。

watch方法

接着采用异步的方式--- ensureGone() , 来检测该activity是否能被GC回收

ensureGone方法

ensureGone方法内部2个核心方法:removeWeaklyReachableReferences() 和 gone() .

知识补充: 使用引用队列ReferenceQueue来创建WeakReference对象,当WeakReference所引用的Object,在某一时刻变为“弱可达” (JVM规定的可GC回收状态)的时候,对此Object的弱引用会被清除,同时该WeakReference会入队ReferenceQueue中。

removeWeaklyReachableReferences方法,就是通过遍历取出ReferenceQueue中的KeyedWeakReference,来判定其所引用的activity是已达到GC可回收状态,同时将对应的key从retainedKeys集合中移除。后续通过调用gone方法,返回ture,说明如果该key已经不在retainedKeys集合中,说明key对应的activity已达可回收状态,没有内存泄露风险。

否则,会手动触发一次系统GC,再尝试一次刚才的判断流程。如果gone方法仍然返回false,说明已经存在内存泄露风险,将会dump当前堆内存情况,将dump file交给HeapAnalyzerService来分析:

HeapAnalyzerService

最终通过 HeapAnalyzer.checkForLeak() 来 计算出 activity实例  到GC roots的最短强引用路径。

计算到GC roots的最短路径
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容