LeakCanary-------快速简单排查Android中的内存泄露

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/dfskhgalshgkajghljgh/article/details/53929201

1. 前言

众所周知,android开发过程中,内存是非常重要的,但是项目上线后经常会有低概率的OOM的错误,及内存溢出。内存溢出原因很多,可能加载图片过大,但是大部分原因是存在内存泄漏。之前检测内存泄漏一直用mat,但是这个工具使用起来比较麻烦,大部分人宁可选择忽视低概率的oom导致的crash。(mat使用方法:http://blog.csdn.net/dfskhgalshgkajghljgh/article/details/50513985)现在LeakCanary的出现使得定位内存泄漏变得异常简单。
LeakCanary对应github地址:https://github.com/square/leakcanary

2.使用方法

1)在项目的build.gradle文件添加:

    debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5'
    releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'
    testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'

可以看到,debugCompile跟releaseCompile 引入的是不同的包, 在 debug 版本上,集成 LeakCanary 库,并执行内存泄漏监测,而在 release 版本上,集成一个无操作的 wrapper ,这样对程序性能就不会有影响。

2)在Application类添加:

public class LCApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        if (LeakCanary.isInAnalyzerProcess(this)) {
            // This process is dedicated to LeakCanary for heap analysis.
            // You should not init your app in this process.
            return;
        }
        LeakCanary.install(this);
        // Normal app init code...
    }
}

LeakCanary.install() 会返回一个预定义的 RefWatcher,同时也会启用一个 ActivityRefWatcher,用于自动监控调用 Activity.onDestroy() 之后泄露的 activity。

如果是简单的检测activity是否存在内存泄漏,上面两个步骤就可以了,是不是很简单。
那么当某个activity存在内存泄漏的时候,会有什么提示呢?LeakCanary会自动展示一个通知栏,点开提示框你会看到引起内存溢出的引用堆栈信息。

这里写图片描述

3.具体使用代码

1)Application 相关代码:

public class LCApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        if (LeakCanary.isInAnalyzerProcess(this)) {
            // This process is dedicated to LeakCanary for heap analysis.
            // You should not init your app in this process.
            return;
        }
        LeakCanary.install(this);
        // Normal app init code...
    }

}

2)泄漏的activity类代码:

public class MainActivity extends Activity {

    private Button next;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        next = (Button) findViewById(R.id.next);
        next.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, SecondActivity.class);
                startActivity(intent);
                finish();
            }
        });
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    System.out.println("=================");
                }
            }
        }).start();
    }
}

当点击next跳到第二个界面后,LeakCanary会自动展示一个通知栏,点开提示框你会看到引起内存溢出的引用堆栈信息,如上图所示,这样你就很容易定位到原来是线程引用住当前activity,导致activity无法释放。

4.其他功能

上面提到,LeakCanary.install() 会返回一个预定义的 RefWatcher,同时也会启用一个 ActivityRefWatcher,用于自动监控调用 Activity.onDestroy() 之后泄露的 activity。现在很多app都使用到了fragment,那fragment如何检测呢。

1)Application 中获取到refWatcher对象。

public class LCApplication extends Application {

    public static RefWatcher refWatcher;

    @Override
    public void onCreate() {
        super.onCreate();
        if (LeakCanary.isInAnalyzerProcess(this)) {
            // This process is dedicated to LeakCanary for heap analysis.
            // You should not init your app in this process.
            return;
        }
        refWatcher  = LeakCanary.install(this);
        // Normal app init code...
    }
}

2)使用 RefWatcher 监控 Fragment:

public abstract class BaseFragment extends Fragment {
  @Override public void onDestroy() {
    super.onDestroy();
    RefWatcher refWatcher = LCApplication.refWatcher;
    refWatcher.watch(this);
  }
}

这样则像监听activity一样监听fragment。其实这种方式一样适用于任何对象,比如图片,自定义类等等,非常方便。
下一篇将介绍LeakCanary的检测原理,先学会使用,再了解原理。

5.源码下载地址

demo下载地址


如有错误欢迎指出来,一起学习。

交流讨论群
群号:469890293

猜你喜欢

转载自blog.csdn.net/dfskhgalshgkajghljgh/article/details/53929201