LeakCanary使用简介
来源:互联网 发布:碑文排版软件 编辑:程序博客网 时间:2024/05/22 04:41
这一篇博客主要记录一下LeakCanary的使用方式。
一、LeakCanary简介
目前,Java程序最常用的内存分析工具是MAT。
MAT的使用比较简单,但分析对应数据的步骤较为繁琐,结果也不够直观。
针对这个情况,Square公司为Android开发者,供了一个自动检测内存泄漏的工具,即LeakCanary。
LeakCanary被集成到Android工程后,一旦发现应用出现内存泄露问题,
就会主动弹出一个通知,然后在通知拉起的界面上,显示出问题的详细信息。
LeakCanary是一个开源工具,感兴趣的朋友可以研究一下它的源码,
由于我并没有深入分析过,因此此处仅结合网上的资料,简要记录一下它的原理。
1.1 发现潜在泄漏对象
LeakCanary被使用后,将会创建一个RefWatcher对象。
RefWatcher对象的watch方法被调用后,将会使用WeakReference引用Activity、Fragment等对象。
同时,RefWatcher会为这些对象生成唯一的Key值,然后将每个对象的Key、WeakReference与ReferenceQueue关联起来。
此外,LeakCanary会创建一个集合retainedKeys保存所有对象的Key值。
系统每次GC时,LeakCanary都可以扫描ReferenceQueue,
得到被释放对象的WeakReference(弱引用对象被释放后,对应的引用将被添加到ReferenceQueue中)。
然后,根据映射关系,LeakCanary得到WeakReference对应的Key值,
并将这些Key值从retainedKeys中移除。
于是,每次GC后,retainedKeys中剩余Key对应的对象,就是潜在的内存泄漏对象。
上述整个过程,基本思路如下图所示:
1.2 分析引用链
LeakCanary找到未被释放的对象后,必须分析该对象的引用关系,
才能确定该对象是否会导致内存泄漏。
为了完成这部分工作:LeakCanary会利用VMDebug与HAHA生成对象的最短引用链。
这一部分工作的依据是:VM 会有堆内各个对象的引用情况,并能以 hprof 文件导出。
HAHA作为square提供的Android 堆分析库,可以分析hprof文件生成Snapshot。
最终,LeakCanary利用Snapshot查询对象的最短引用链。
上述整个过程,基本思路如下图所示:
得到最短引用链后,LeakCanary就会弹出通知,将信息显示在界面上。
根据引用链,我们就可以比较快速的定位和分析问题。
1.3 整体流程图
上述过程整体的流程图基本上可以总结为下图,这里偷懒盗了个图:
二、使用LeakCanary
简单了解LeakCanary的原理后,我们就可以看看如何使用LeakCanary了。
2.1 导入LeakCanary对应的Jar包
在使用LeakCanary前,首先需要导入对应的Jar包。
以Android Studio为例,我们可以直接open module settings,
然后在Dependencies中搜索并增加leakCanary所需的库。
正常情况下,我们需要同时引入release和debug版本的库,
然后通过配置build.gradle,使得leakCanary仅在debug版本工作。
例如,在build.gradle中增加以下信息:
dependencies { debugCompile 'com.squareup.leakcanary:leakcanary-android:1.x' releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.x'}
2.2 监控Activity是否泄露
导入LeakCanary后,监控Activity是否泄露的操作极其简单。
我们只需要重写Application类的onCreate方法即可,如下所示:
public class App extends Application { @Override public void onCreate() { super.onCreate(); //仅需这步操作即可 //返回一个预定义的 RefWatcher //同时也会启用一个ActivityRefWatcher,自动监控调用Activity.onDestroy()之后泄露的activity LeakCanary.install(this); .................. }}
如果检测到某个 activity 有内存泄露 ,LeakCanary 就是自动地显示一个通知。
2.3 监控其它对象是否泄露
2.2中提到的方法,主要用于检测应用中的Activity是否泄露。
如果需要监控应用中的其它对象是否泄露,则需要主动观察该对象。
当然,这部分工作也及其容易。
我们以监控Fragment为例,看看对应的操作:
public class App extends Application { //Application为整个应用保存全局的RefWatcher private RefWatcher refWatcher; @Override public void onCreate() { super.onCreate(); refWatcher = LeakCanary.install(this); } public static RefWatcher getRefWatcher(Context context) { App application = (App) context.getApplicationContext(); return application.refWatcher; }}
之后就可以使用 RefWatcher监控 Fragment了,例如:
public abstract class BaseFragment extends Fragment { @Override public void onDestroy() { super.onDestroy(); RefWatcher refWatcher = App.getRefWatcher(getActivity()); refWatcher.watch(this); }}
- LeakCanary使用简介
- LeakCanary使用
- LeakCanary使用
- LeakCanary使用
- 使用leakCanary
- leakcanary使用
- LeakCanary 中的 IdleHandler简介
- LeakCanary的使用
- LeakCanary的使用
- LeakCanary的使用
- leakCanary 在eclipse使用
- LeakCanary的使用
- LeakCanary的使用
- LeakCanary的简单使用
- Leakcanary初使用小记
- LeakCanary 使用一
- LeakCanary的使用
- leakcanary 使用问题
- stderr,stdin,stdout详解
- L1-006. 连续因子
- Android杂谈(24)Service+BroadcastReceiver+数据库+HttpURLConnection实现断点续传(下)
- javaScript编码
- 1001: [BeiJing2006]狼抓兔子
- LeakCanary使用简介
- 解决centos 7系统自定义脚本自启动失败的问题
- java9——while循环
- linux下(CentOS6.4)mysql安装
- app同包同签名不能安装问题
- Button点击事件的四种方法
- java测试框架-junit4
- Attempt to read from field 'int android.graphics.Rect.bottom' on a null object reference
- numpy