android内存泄漏原因分析,Android性能优化之LeakCanary内存泄漏检测原理分析

LeakCanary内存泄漏检测原理分析

一、LeakCanary原理介绍LeakCanary如何检测内存泄漏的呢?主要分为7步:

1、RefWatcher.watch()创建了一个KeyedWeakReference用于去观察对象。

2、然后,在后台线程中,它会检测引用是否被清除了,并且是否没有触发GC。

3、如果引用仍然没有被清除,那么它将会把堆栈信息保存在文件系统中的.hprof文件里。

4、HeapAnalyzerService被开启在一个独立的进程中,并且HeapAnalyzer使用了HAHA开源库解析了指定时刻的堆栈快照文件heap dump。

5、从heap dump中,HeapAnalyzer根据一个独特的引用key找到了KeyedWeakReference,并且定位了泄露的引用。

6、HeapAnalyzer为了确定是否有泄露,计算了到GC Roots的最短强引用路径,然后建立了导致泄露的链式引用。

7、这个结果被传回到app进程中的DisplayLeakService,然后一个泄露通知便展现出来了。

官方原理解释是:

在一个Activity执行完onDestroy后,将它放入到WeakReference中,然后将这个WeakReference类型的Activity的对象与ReferenceQueue关联,注意: 如果一个对象要被GC回收了,会把它引用的对象放入到ReferenceQueue中。这时候只需要在ReferenceQueue中去查找是否存在该对象,如果没有就执行一个GC,再次查找,如果还是没有,则说明该对象可能无法被回收,也就可能发生了内存泄漏,最后使用HAHA这个开源库取分析dump之后的heap内存。

二、为什么要使用LeakCanary我们知道内存泄漏问题的排查有很多种方法, 比如说,Android Studio 自带的 Profile 工具、MAT(Memory Analyzer Tool)、以及LeakCanary。 选择 LeakCanary 作为首选的内存泄漏检测工具主要是因为它能实时检测泄漏并以非常直观的调用链方式展示内存泄漏的原因。

三、LeakCanary的使用

1、在app中的build.gradle中配置:dependencies {

debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.6.2'

releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.6.2'

// 可选,如果你使用支持库的fragments的话

debugImplementation 'com.squareup.leakcanary:leakcanary-support-fragment:1.6.2'

}

2、然后在Application中配置:public class WanAndroidApp extends Application {

private RefWatcher refWatcher;

public static RefWatcher getRefWatcher(Context context) {

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

return application.refWatcher;

}

@Override public void onCreate() {

super.onCreate();

if (LeakCanary.isInAnalyzerProcess(this)) {

// 1

return;

}

// 2

refWatcher = LeakCanary.install(this);

}

}

在注释1处,会首先判断当前进程是否是Leakcanary专门用于分析heap内存的而创建的那个进程,即HeapAnalyzerService所在的进程,如果是的话,则不进行Application中的初始化功能。如果是当前应用所处的主进程的话,则会执行

注释2处的LeakCanary.install(this)进行LeakCanary的安装。只需这样简单的几行代码,我们就可以在应用中检测是否产生了内存泄露了。当然,这样使用只会检测Activity是否发生内存泄漏,如果要检测Fragment在执行完onDestroy()之后是否发生内存泄露的话,则需要在Fragment的onDestroy()方法中加上如下两行代码去监视当前的Fragment:

RefWatcher refWatcher = WanAndroidApp.getRefWatcher(_mActivity);

refWatcher.watch(this);

上面的RefWatcher其实就是一个引用观察者对象,是用于监测当前实例对象的引用状态的。从以上的分析可以了解到,核心代码就是LeakCanary.install(this)这行代码,接下来,就从这里出发将LeakCanary一步一步进行拆解。

四、LeakCanary源码分析待定。。。

五、LeakCanary执行的流程

android内存泄漏原因分析,Android性能优化之LeakCanary内存泄漏检测原理分析_第1张图片

六、总结LeakCanary 的原理总结如下

监听 Activity 的生命周期

在 onDestroy 的时候,创建相应的 Refrence 和 RefrenceQueue,并启动后台进程去检测

一段时间之后,从 RefrenceQueue 读取,若读取不到相应 activity 的 Refrence,有可能发生泄露了,这个时候,再触发 gc,一段时间之后,再去读取,若在从 RefrenceQueue 还是读取不到相应 activity 的 refrence,可以断定是发生内存泄露了

发生内存泄露之后,dump,分析 hprof 文件,找到泄露路径(使用 haha 库分析)

其中,比较重要的是如何确定是否发生内存泄露,而如何确定发生内存泄露最主要的原理是通过 Refrence 和 RefrenceQueue。

你可能感兴趣的:(android内存泄漏原因分析)