您现在的位置是:首页 >学无止境 >源码:LeakCanary网站首页学无止境
源码:LeakCanary
一、介绍
自动检测内存泄漏的检查工具
二、使用
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.5'
debugImplementation只在debug模式的编译和最终的debug apk打包时有效
Memory Profiler 使用步骤
- 生成的内存泄漏快照 会放在sdcard/Download/leakcanary-包名下
- 直接双击打开,把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回收时,该对象将会被加入到引用队列的末尾。
-
为要被观察的对象,添加一个弱引用对象与之关联,并且为这个对象添加一个唯一标识,然后把弱引用对象放到观察列表中。
-
然后会不断的监听引用队列,在界面退出时,过5秒钟如果引用队列中找不到观察列表中的对象(因为如果对象被释放,会添加到引用队列),那么就把它移动到怀疑列表中。
-
最后把怀疑列表中的对象进行可达性分析,如果还存在一条引用链,则说明该对象发生了内存泄露