Bootstrap

LeakCanary--原理及应用

LeakCanary–原理及应用

一、简介

1.1 名字由来

LeakCanary ,直译为泄露的金丝雀,名称来源于一个关于金丝雀的故事。在17世纪的英国,煤矿业还没发展出检测瓦斯泄露探测仪,于是矿工们在下矿井时就带一只金丝雀。金丝雀对瓦斯及其敏感,稍微有瓦斯泄漏,它就会停止歌唱,浓度再高一些,金丝雀就会直接中毒身亡。而这时候,人比他皮糙肉厚一些,人类迟钝的感觉是完全没有意识到瓦斯的存在的。如果此时再不及时逃出矿坑,那么死的就是矿工了,正式借用了这层寓意,才起了LeakCanary这个名字,正如这个组件的功能一样,这个组件意在像检测瓦斯泄露的金丝雀一样,在危险发生之前,提前的检测内存泄露。

1.2 功能简介

LeakCanary是一个专门针对于Android的 内存泄露检测的库,LeakCanary通过对Android框架内部知识的了解,监听Activity与fragment的生命周期,实现对Activity,Fragment,Fragment View和ViewModel实例的内存泄露的监控,被监控的对象,在垃圾回收的5秒后没有回收掉的话,这个对象就会被认为是被保留了,和潜在内存泄露的

1.3 发展史

起始版本,仅Activity的监控

1.6.1 版本,加入了对Fragment的监控

1.6.2版本,加入了对Fragment view的监控

2.2版本,加入了对ViewModel的监控

正如功能简介中描述的一样,LeakCanary通过对Android框架内部知识的了解,来实现的泄露监控,从发展史上我们也能看到,随着对android代码了解的加深,其检测能力,也逐渐丰富

1.4 官网网址

https://square.github.io/leakcanary/fundamentals/

二、接入方式

2.1 接入:

dependencies {
  
    debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.3'
}

2.2 验证接入是否成功:

通过Logcat 查看 输出打印 D LeakCanary: LeakCanary is running and ready to detect leaks

三、检测与分析

3.1、检测

当按照接入方式接入成后,正常操作APP即可,当有内存泄露发生时,会在在桌面生成内存泄露的图标,点击进入后可以查看相关的堆栈信息

3.2、分析

1.读懂泄露的信息

├─ :表示一个java对象

│ ↓ :下面一行的对象的一个实例被对当前行的对象引用

**╰→:**表示泄露的对象

2.读取顺序,从泄露的位置向前读

3.3、举例:

具体实例

四、运作原理

1、源码解读:

阅读源码前,请思考几个问题:

它是如何做到仅一行配置代码就完成监控的

它是在什么时机,去判断是否存在内存泄露的

它是通过什么原理,来判断是否存在内存泄露的

2、总结:

它是如何做到仅一行配置代码就完成监控的

1.ContentProvider的onCreate的调用时机是在application onCreate之前调用的,即在应用启动时,完成了自身代码的调用,降低了接入方在java代码层面上的接入成本

2.通过占位符的方式,简化了接入方在manifest文件上的接入成本

3.debugImplementation 仅在debug模式下生效,降低了使用implementation时需要依赖空包的接入成

它是在什么时机,去判断是否存在内存泄露的

1.Activity:通过在Application中注册registerActivityLifecycleCallbacks绑定Activity生命周期回调,并在onActivityDestroyed回调中监控Activity

2.Fragment:通过在Application中注册registerActivityLifecycleCallbacks绑定Activity生命周期回调,并在onActivityCreated回调中,通过在Activity中注册注册FragmentLifecycleCallbacks回调,并在onFragmentDestroyed回调时,监控fragment

3.Fragment View:通过在Application中注册registerActivityLifecycleCallbacks绑定Activity生命周期回调,并在onActivityCreated回调中,通过在Activity中注册注册FragmentLifecycleCallbacks回调,并在onFragmentViewDestroyed回调中监控Fragment View

4.ViewModel:针对AndroidX库中的Activity,对于Activit,在onActivityCreated回调中注册监听,对于Fragment,在onFragmentCreated回调中注册监听,,,在ViewModel的onCleared回调中监控ViewModel

它是通过什么原理,来判断是否存在内存泄露的

是利用了WeakRefrence + RefrenceQueue的机制(仅被弱引用持有的对象,当对象被回收时,会存入到引用队列中),从引用队列中不断的获取对象,将已确认被GC的对象剔除,剩余未被回收的对象则定义为可能泄露的对象,当达到一定的判断条件时,通知用户内存泄露

五、个人理解

AppWatcher.objectWatcher.watch(myDetachedView, “View was detached”)

阅读完源码,说下个人对下面这个方法的理解。android是在不断发展完善的,就像viewmodel一样,是新增的检测类型,这个方法的作用,就是当我们自定义了一些存在生命周期的东西时,在改对象生命周期结束的时候,可以手动的调用这个方法,来监控自定义对象的生命周期

;