leakcanary 内存优化框架源码解析

造成内存泄露的原因
1.单例传入Activity的context上下文,导致activity关闭了,但是还是被单例模式引用,内存无法回收
解决:采用getApplicationContext
2.非静态内部类会默认持有外部类的引用
解决:使用静态内部类
3.Handle造成的内存泄露
解决:使用静态内部类+activity弱引用
4.new 一个线程造成的
使用静态内部类
5.webview造成的
通过killprocess杀掉进程解决

总结一下:大部分都是非静态内部类造成的

Java的4种对象引用:
强引用 StrongReference (宁愿抛出oom错误,让程序终止,GC(垃圾回收器)也不会回收)
软引用 SoftReference (内存足够,GC不会回收,内存不够的时候才回收)
弱引用 WeakRefrence (当垃圾回收器回收的时候,不区分内存够不够,都会回收)
虚引用 :没有任何引用,随时可以回收

1、leakcanary的原理
2、Activity的泄露监测机制

leakcanary的原理(利用弱引用来监控activity):
1、Activity Destroy之后将它放在一个WeakReference弱引用中
2、这个WeakReference关联到一个ReferenceQueue(引用队列)
3、查看ReferenceQueue队列是否存在activity的引用
4、如果Activity泄露了,Dump出heap信息,然后再去分析泄露路径

软引用和弱引用对象被GC回收了,Java虚拟机会把这个引用加入到与之关联的引用队列(ReferenceQueue)中。

源码流程:
1、创建RefWatcher,调用ActivityRefWatcher.install,启动一个ActivityRefWatcher,ActivityRefWatcher就是为了监视Activity的回收情况
2、通过ActivityLifecycleCallbacks对象把activity的onDestroy生命周期和ActivityRefWatcher类相关联。
3、最后在线程池中分析内存泄露

leakcanary如何在线程池中分析内存泄露?

在线程池中HeapAnalyzerService extends IntentService ,其实是一个Service的onHandleIntent中处理的,在这个Service中调用了一个checkForLeak方法,

checkForLeak是整个leakcanary中最重要的一个方法:
1、把.hprof转为Snapshot(内存快照)
2、优化gcroots
3、找出泄露的对象和找出泄露对象的最短路径

那么怎么找出泄露对象和泄露对象的最短路径呢?
要关注2个方法:
findLeakingReference方法:找到内存泄露的引用对象,原理是
1、在snapshot快照中找到第一个弱引用。
2、遍历这个对象的所有实例,如果key值和最开始定义封装的key值相同,那么返回这个泄露对象。

findLeakTrace方法:根据内存泄露对象的引用找到最短路径

2个方法的最终总结:
1、解析.hprof文件,把这个文件封装成snapshot内存快照
2、根据弱引用和前面定义的key值来确定泄露的对象
3、通过泄露对象的引用找到最短路径,作为结果反馈出来

2.0以后无需初始化:

1,由于我们添加了LeakCanary2的依赖,而在他依赖的leakcanary-object-watcher-android工程中,注册了一个provider。
2,当app进程启动的时候,会自动创建注册这个provider,并执行其中的onCreate方法。
3,在这个onCreate方法中,调用了LeakCanary的install方法,创建各自的watcher,并注册监听了application的ActivityLifecycleCallback。

你可能感兴趣的:(框架源码解析,leakcanary)