当前位置: 移动互联网学院 > Android开发 > Android Leakcanary使用教程
Android Leakcanary使用教程 时间:2017-04-14     来源:Android开发学习网

LeakCanary是一个用来检查Android下内存泄漏的开源库,从而帮助我们能够以简洁明了的方式定位Android内存泄露隐患。这篇文章主要介绍Android Leakcanary的使用方法、架构和其背后的实现原理。

虽然我们可以通过MAT对内存泄漏问题进行分析,但是毕竟步骤繁琐,还不一定能从茫茫对象中定位到异常发生现场。如果有一个工具能自动完成这些事情,甚至在发生OOM之前,就把内存泄漏报告给你,岂不更好?Android LeakCanary 就是用来干这个事情的。在测试你的App时,如果发生了内存泄漏,状态栏上会有通知,同时在logcat上也会有相应的log输出。

一. Android Leakcanary使用方法

1. 使用Leakcanary监控Activity泄露的方法

我们经常把 Activity 当作为 Context 对象使用,在不同场合由各种对象引用 Activity。所以,Activity 泄漏是一个重要的需要检查的内存泄漏之一。

public class ExampleApplication extends Application {

public static RefWatcher getRefWatcher(Context context) {

ExampleApplication application = (ExampleApplication) context.getApplicationContext();

return application.refWatcher;

}

private RefWatcher refWatcher;

@Override public void onCreate() {

super.onCreate();

refWatcher = LeakCanary.install(this);

}

}

LeakCanary.install()返回一个配置好了的 RefWatcher 实例。它同时安装了 ActivityRefWatcher 来监控 Activity 泄漏。即当 Activity.onDestroy() 被调用之后,如果这个 Activity 没有被销毁,logcat 就会打印出如下信息告诉你内存泄漏发生了。

* com.example.leakcanary.MainActivity has leaked:

* GC ROOT thread java.lang.Thread. (named 'AsyncTask #1')

* references com.example.leakcanary.MainActivity$2.this$0 (anonymous class extends android.os.AsyncTask)

* leaks com.example.leakcanary.MainActivity instance

* Reference Key: c4d32914-618d-4caf-993b-4b835c255873

* Device: Genymotion generic Google Galaxy Nexus - 4.2.2 - API 17 - 720x1280 vbox86p

* Android Version: 4.2.2 API: 17

* Durations: watch=5100ms, gc=104ms, heap dump=82ms, analysis=3008ms

LeakCanary 自动检测 Activity 泄漏只支持 Android ICS 以上版本。因为 Application.registerActivityLifecycleCallbacks() 是在 API 14 引入的。如果要在 ICS 之前监测 Activity 泄漏,可以重载 Activity.onDestroy() 方法,然后在这个方法里调用 RefWatcher.watch(this) 来实现。

2.使用Leakcanary监控Fragment泄漏的方法

public abstract class BaseFragment extends Fragment {

@Override

public void onDestroy() {

super.onDestroy();

RefWatcher refWatcher = ExampleApplication.getRefWatcher(getActivity());

refWatcher.watch(this);

}

}

当 Fragment.onDestroy() 被调用之后,如果这个 fragment 实例没有被销毁,那么就会从 logcat 里看到相应的泄漏信息。

3. 使用Leakcanary监控其他泄漏

RefWatcher refWatcher = ExampleApplication.getRefWatcher(getActivity());

refWatcher.watch(someObjNeedGced);

当 someObjNeedGced还在内存中时,就会在 logcat 里看到内存泄漏的提示。

4. 如何集成LeakCanary库

dependencies {

debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3'

releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3'

}

在 debug 版本上,集成 LeakCanary 库,并执行内存泄漏监测,而在 release 版本上,集成一个无操作的 wrapper ,这样对程序性能就不会有影响。

二.Android Leakcanary实现原理

1. LeakCanary工作流程图

 

Android Leakcanary使用教程
Android Leakcanary工作流程图

2.LeakCanary的机制如下:

RefWatcher.watch()会以监控对象来创建一个 KeyedWeakReference弱引用对象

在 AndroidWatchExecutor的后台线程里,来检查弱引用已经被清除了,如果没被清除,则执行一次 GC

如果弱引用对象仍然没有被清除,说明内存泄漏了,系统就导出 hprof 文件,保存在 app 的文件系统目录下

HeapAnalyzerService启动一个单独的进程,使用 HeapAnalyzer来分析 hprof 文件。它使用另外一个开源库 HAHA。

HeapAnalyzer通过查找 KeyedWeakReference弱引用对象来查找内在泄漏

HeapAnalyzer计算 KeyedWeakReference所引用对象的短强引用路径,来分析内存泄漏,并且构建出对象引用链出来。

内存泄漏信息送回给 DisplayLeakService, 它是运行在 app 进程里的一个服务。然后在设备通知栏显示内存泄漏信息。

以上就是对Android Leakcanary使用方法和原理的讲解内容,希望对大家在开发过程中定位Android内存泄露隐患有所帮助。