美文网首页
LeakCanary内存泄露检测

LeakCanary内存泄露检测

作者: AJI大侠 | 来源:发表于2018-03-28 16:06 被阅读56次
    1. LeakCanary简介
    • LeakCanary是Square公司开源的一个检测内存的泄露的函数库,可以方便地和你的项目进行集成,在Debug版本中监控Activity、Fragment等的内存泄露

    • LeakCanary集成到项目中之后,在检测到内存泄露时,会发送消息到系统通知栏。点击后打开名称DisplayLeakActivity的页面,并显示泄露的跟踪信息,Logcat上面也会有对应的日志输出

    1. 内存泄漏简介
    • 为什么会产生内存泄漏?
      当一个对象不需要使用本该回收时,有另外一个正在使用的对象持有它的引用,从而导致它不能回收停留在堆内存中,这就产生了内存泄漏

    • 内存泄露对程序产生的影响?
      内存泄漏是造成应用程序OOM的主要原因之一。Android系统为每个应用程序分配有限的内存,当应用中内存泄漏较多时,就难免会导致应用所需要的内存超出系统分配限额,从而导致OOM应用Crash

    1. LeakCanary接入
    • 我们以LeakCanaryTest项目进行演示如何在项目中接入LeakCanary,项目目录如下:


      1522222494(1).png

      整个结构非常的简单如上图所示

    • 在主项目main模块的build.gradle文件中添加LeakCanary相关依赖 -/main/build.gradle文件

     dependencies {
        implementation fileTree(dir: 'libs', include: ['*.jar'])
        implementation 'com.android.support:appcompat-v7:26.1.0'
    
        // 添加leakcanary相关的依赖
        // 在release版本中,使用的是LeakCanary的no-op版本,也就是没有实际代码和操作的Wrapper版本
        // 只包含LeakCanary和RefWatcher类的空实现,这样不会对生成的APK包体积和应用性能造成影响
        debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.5.4'
        releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.4'
    }
    
    • 初始化LeakCanary在主项目main模块的QApplication的onCreate()方法中初始化LeakCanary
      leakcanary.com.leakcanarytest.FFApplication文件
    public class FFApplication extends Application
    {
        @Override
        public void onCreate()
        {
            super.onCreate();
            if (LeakCanary.isInAnalyzerProcess(this))
            {
                return;
            }
            LeakCanary.install(this);
        }
    }
    

    这样我们就完成了一个项目的LeankCanary的简单接入

    1. LeakCanary检测
      下面我们以常见内存—单例造成的内存泄露为例进行实践
    • 单例内存泄露模拟
      LeakcanaryTest\app\src\main\java\leakcanary\com\leakcanarytest\TestManager.java
    public class TestManager
    {
        //单例静态特性使得单例的生命周期和应用的生命周期一样长
        private static TestManager instance;
        private Context context;
    
        /**:
         * 传入的是Application的Context,则生命周期和单例生命周期一样长;
         * 传入的是Activity的Context,由于该Context和Activity的生命周期一样长,当Activity退出的时候它的内存不会被回收,因为单例对象持有它的引用;
         */
        private TestManager(Context context) {
            this.context = context;
        }
    
        public static TestManager getInstance(Context context) {
            if (instance == null) {
                instance = new TestManager(context);
            }
            return instance;
        }
    }
    

    5.检测消息通知

    • 运行App到LeakCanaryActivit页面并退出,在检测到内存泄露的时候,会发送消息到系统通知栏如下图所示


      1522223392(1).png 1522223450(1).png
    • 对于开发人员这时可以很清晰的看到内存泄露了并及时修复代码!

    1. LeakCanary原理
    • 源码里面的watch()函数会为被监控的对象创建一个KeyedWeakReference弱引用对象,是WeakReference对的子类,增加了键值对信息,后面会根据指定的键key找到弱引用对象
    • 在后台线程中,检查KeyedWeakReference弱引用是否已经被清除。如果没有,则触发一次GC,GC之后,如果弱引用对象依然存在,说明发生了内存泄露
    1. 对于项目的好处
    • 对于开发人员来说,可以优化app代码,减少内存泄漏和bug,有利于后期维护
    • 对于测试人员,完善后的APP,可以大大减轻测试的难度和强度
    图片.png

    相关文章

      网友评论

          本文标题:LeakCanary内存泄露检测

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