美文网首页
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