美文网首页
Leakcanary原理使用解析

Leakcanary原理使用解析

作者: 单线程的Cuke | 来源:发表于2019-03-27 17:19 被阅读0次

    Getting Started

    在build.gradle:

    dependencies {
     debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.6.3'
     releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.6.3'
     // Optional, if you use support library fragments:
     debugImplementation 'com.squareup.leakcanary:leakcanary-support-fragment:1.6.3'
    }
    

    application

    public class MyApplication extends Application {
        private RefWatcher refWatcher;
        @Override
        public void onCreate() {
            super.onCreate();
            refWatcher= setupLeakCanary();
        }
    
        private RefWatcher setupLeakCanary() {
            if (LeakCanary.isInAnalyzerProcess(this)) {
                return RefWatcher.DISABLED;
            }
            return LeakCanary.install(this);
        }
    
        public static RefWatcher getRefWatcher(Context context) {
            MyApplication leakApplication = (MyApplication) context.getApplicationContext();
            return leakApplication.refWatcher;
        }
    }
    

    BaseActivity

    public class BaseActivity extends Activity{
        @Override
        protected void onDestroy() {
            super.onDestroy();
            RefWatcher refWatcher =MyApplication.getRefWatcher(this);
            refWatcher.watch(this);
        }
    }
    

    更多用法

    原理介绍

    RefWatcher.watch() 会创建一个内存泄露的观察对象[KeyedWeakReference]。在后台进程中,会检查引用对象是否被清除或者触发回收,如果没有被清除或者回收,leaks讲相关引用存储在一个.hprof的文件内。
    HeapAnalyzerService 运行在一个独立的process,HeapAnalyzer用HAHA框架[一个Android heap分析框架]解析堆栈。
    由于一个唯一的引用键,HeapAnalyzer在堆转储中找到KeyedWeakReference,并找到泄漏的引用。
    HeapAnalyzer 计算出内存泄露的链
    结果通过 DisplayLeakService打印在APP进程中显示。

    1.触发检测
    每次当Activity/Fragment执行完onDestroy生命周期,LeakCanary就会获取到这个Activity/Fragment,然后初始化RefWatcher对它进行分析,查看是否存在内存泄漏。

    2.判断分析是否内存泄露
    首先尝试着从ReferenceQueue队列中获取待分析对象(软引用和弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用或弱引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个软引用或弱引用加入到与之关联的引用队列中),如果不为空,那么说明正在被系统回收,如果直接就返回DONE,说明已经被系统回收了,如果没有被系统回收,可能存在内存泄漏,手动触发系统GC,然后再尝试移除待分析对象,如果还存在,说明存在内存泄漏。

    3.分析内存泄漏
    确定有内存泄漏后,调用heapDumper.dumpHeap()生成.hprof文件目录。HAHA 是一个由 square 开源的 Android 堆分析库,分析 hprof 文件生成Snapshot对象。Snapshot用以查询对象的最短引用链。找到最短引用链后,定位问题,排查代码将会事半功倍。


    image.png image.png

    如何解决内存泄露

    为了解决内存泄露,你需要去看看使用或者引用是不是导致泄露,Leakcanary工具会抓到泄露并显示出来,可以根据相关代码检查是否内存泄露。
    有相关问题可以在Stack Overflow 提问题。

    总结

    1.AOSP中也会存在内存泄露
    2.LeakCanary对内存泄露检测有效,但是对于service泄露无法检测到

    1. 无法走到destory周期的内存泄露无法解决。
    参考资料

    1.leakcanary
    2.性能优化工具(九)-LeakCanary
    3.Leaks 原理解析

    相关文章

      网友评论

          本文标题:Leakcanary原理使用解析

          本文链接:https://www.haomeiwen.com/subject/yxizvqtx.html