您现在的位置是:首页 >学无止境 >源码:LeakCanary网站首页学无止境

源码:LeakCanary

郑子 2023-05-24 00:00:03
简介源码:LeakCanary

一、介绍

自动检测内存泄漏的检查工具

二、使用

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

debugImplementation只在debug模式的编译和最终的debug apk打包时有效

Memory Profiler 使用步骤

  1. 生成的内存泄漏快照 会放在sdcard/Download/leakcanary-包名下
  2. 直接双击打开,把Activity/Fragment Leaks 和 Project Classes 勾选上,就可以看到泄漏的Activity/Fragment

三、内存泄漏常见分析工具

  • MAT:Memory Analyzer Tools
  • Memory Profiler:AS自带
  • LeakCan ary

四、LeakCanary源码分析

1.初始化

  • 在使用LeakCanary的时候直接一行依赖就可以了,不需要用户调用初始化。
  • leakcanary 通过 ContentProvider 进行初始化
  • AppWatcherInstaller#oncreate()中调用了真正的初始化代码AppWatcher.manualInstall(application)
  • AndroidManifest.xml中注册该provider,注册的ContentProvider会在 application 启动的时候自动回调 oncreate方法。
internal sealed class AppWatcherInstaller : ContentProvider() {
  /**[MainProcess] automatically sets up the LeakCanary code that runs in the main app process. */
  internal class MainProcess : AppWatcherInstaller()
  internal class LeakCanaryProcess : AppWatcherInstaller()
  override fun onCreate(): Boolean {
    val application = context!!.applicationContext as Application
    AppWatcher.manualInstall(application)
    return true
  }
  //...
  }

AppWatcherInstaller类直接继承ContentProvider,而ContentProvider是注册即执行

AppWatcherInstaller的注册就是在leakcanary-object-watcher-android文件夹的AndroidManifest.xml中

    <application>
        <provider
            android:name="leakcanary.internal.AppWatcherInstaller$MainProcess"
            android:authorities="${applicationId}.leakcanary-installer"
            android:enabled="@bool/leak_canary_watcher_auto_install"
            android:exported="false" />
    </application>

总结:

        App的创建过程,是由zygote fork 一个app进程,然后会调用ActivityThread的main函数,在ActivityThread里,完成 Application的初始化前,会先完成contentProvider的初始化。

        LeakCanary就是使用这个原理,创建一个ContentProvider,通过它来完成初始化

2.自动检测并报告内存泄漏

        LeakCanary完成初始化的时候,会通过注册监听Activity、Fragment的生命周期。

        核心类:RefWather,来实现内存泄露检测

        主要是通过弱引用(WeakReference)和引用队列(ReferenceQueue)来检测对象是否被释放。因为在Reference所引用的对象被gc回收时,该对象将会被加入到引用队列的末尾。

  1. 为要被观察的对象,添加一个弱引用对象与之关联,并且为这个对象添加一个唯一标识,然后把弱引用对象放到观察列表中。

  2. 然后会不断的监听引用队列,在界面退出时,过5秒钟如果引用队列中找不到观察列表中的对象(因为如果对象被释放,会添加到引用队列),那么就把它移动到怀疑列表中。

  3. 最后把怀疑列表中的对象进行可达性分析,如果还存在一条引用链,则说明该对象发生了内存泄露

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。