重看LeakCanary

LeakCanary是我很久之前看的东西了,我当时侯对它的印象就是它可以用来检测内存泄漏,具体原理就是将弱引用对象延迟个5s然后看是否被回收,如果没有被回收,那么就说明发生了内存泄漏,其他的也没有仔细地看

现在就详细地梳理一遍这个流程:

1.LeakCanary的使用方法

很简单,我们只需要在build.gradle.kts里面加上

debugImplementation ("com.squareup.leakcanary:leakcanary-android:2.12")

注意,这个leakcanary是2.6的版本,以前,我们需要手动在Application中调用LeakCanary.install(this);进行初始化工作

但是现在2.4的版本之后,就不需要手动调用了,当我们加上上面的那个之后点击sync运行,当我们点击我们AndroidStudio的Run 'app',安装好app之后,你会发现你的手机上会多一个这个app

bc10e0a2b0ac4a3b965bdab91d0a65bb.jpg

 

这个app就会来汇报存在哪些内存泄漏

好,现在有2个问题

1:为什么我们其他的导入用的是

implementation()

而LeakCanary用的是

debugImplementation

2:为什么要生成一个Leaks用来检测内存泄漏

我们分别来看看吧

 

1.1为什么导入用的是debugImplementation

在网上搜到的资料显示的是:

在Android项目中,通常会使用两种依赖配置来引入库:implementation和debugImplementation。其中,implementation配置表示该库是项目的一部分,会被打包到最终的发布版本中;而debugImplementation配置表示该库仅在调试模式下使用,不会被打包到发布版本中。

LeakCanary通常被用于调试和排查内存泄漏问题,因此建议将其导入为debugImplementation。这样,在发布版本中不会包含LeakCanary的代码,避免增加应用的体积和性能开销。

这个怎么理解呢?在AndroidStudio里面双击shift然后你搜索leakcanary然后你随便点进去看它的path你会发现,它的路径都不是在该项目上的,而是在你电脑的gradle路径下面

它的主要目的就是不想让LeakCanary的代码出现在Release版本的项目中

注意哦,这里说的是Release版本的项目,也就仅仅针对于Release版本,不包括Debug版本哦

1.2为什么要生成一个Leaks来检测内存泄漏

搜到的原因是这样的,因为内存泄漏的检查和分析过程涉及到大量复杂的堆转储操作,可能会阻塞主线程影响正常应用的运行,因此LeakCanary将耗时操作转移到单独进程中处理,然后通过Leaks应用以图形化可视的方式方便用户查看。

那这样还有一个疑问了,既然是大量复杂的运算,与其开一个新的进程,为什么我们不新开一个线程来解决呢?

我的理解是使用单独的进程而不是新开一个线程,它的好处就在于不必担心影响主应用的内存分配和其他系统资源,保证独立性方便进行检测

2.LeakCanary的原理

2.1LeakCanary的初始化

LeakCanary的初始化早期是需要我们自己手动在application的onCreate()里面进行初始化的,但是现在导入LeakCanary的包之后就不用我们手动进行初始化了,记住,这里说的是不用手动进行初始化了,不是不用进行初始化了,它会在MainProcessAppWatcherInstaller.kt这个类里面进行初始化,通过调用

AppWatcher.manualInstall()

然后才进行的初始化,那么为什么之前版本的LeakCanary是在Application的onCreate()初始化,而现在是在MainProcessAppWatcherInstaller.kt这个类呢?首先MainProcessAppWatcherInstaller.kt这个类继承自ContentProvider

(其实我感觉很无语的一件事就是MainProcessAppWatcherInstaller.kt他是在gradler的,但是ContentProvider这个类是在SDK里面的)

其中ContentProvider的onCreate()的生命周期是要早于Application的onCreate()方法而要晚于Application的attachBaseContext的生命周期

那么Application的attachBaseContext话,它是当application刚开始进行初始化的时候调用的,当application的初始化执行完毕之后才会调用application的onCreate()方法进行全局性的初始化,比如单例对象的创建。

现在LeakCanary是在MainProcessAppWatcherInstaller.kt中注册就是为了监测application初始化的过程中是否会存在内存泄露问题,可以提供更全面,准确得到内存泄露监测效果

2.2LeakCanary的原理

LeakCanary的原理其实很简单,我们以Activity举例,Android为我们提供了一个Activity的生命周期监测的一个接口 ActivityLifeCycleCallBack接口,当Activity的生命周期处于onDestroyed()的时候,它就会生成一个Activity的弱引用对象并且为这个对象生成一个键,以键值对的方式存进Map中,这个Map中就是用来存储还有哪些对象没有被回收掉,我们通过Handler让这个弱引用对象延迟5s操作,如果它被回收掉,那么它就会被放进一个弱引用队列里面,并且将它从Map中移出调,如果没有被回收调的话 ,那么就会进行手动GC,如果仍然没有被回收掉,那么就说明发生了内存泄露。最终生成一个hprof文件,最开始我们不是说的那个Leaks app嘛,它读取hprof文件里面的数据,分析导致内存泄露的引用链,将分析的结果展示给用户

 

  • 14
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值