Getting Started
在build.gradle:
dependencies {
debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.6.3'
releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.6.3'
// Optional, if you use support library fragments:
debugImplementation 'com.squareup.leakcanary:leakcanary-support-fragment:1.6.3'
}
application
public class MyApplication extends Application {
private RefWatcher refWatcher;
@Override
public void onCreate() {
super.onCreate();
refWatcher= setupLeakCanary();
}
private RefWatcher setupLeakCanary() {
if (LeakCanary.isInAnalyzerProcess(this)) {
return RefWatcher.DISABLED;
}
return LeakCanary.install(this);
}
public static RefWatcher getRefWatcher(Context context) {
MyApplication leakApplication = (MyApplication) context.getApplicationContext();
return leakApplication.refWatcher;
}
}
BaseActivity
public class BaseActivity extends Activity{
@Override
protected void onDestroy() {
super.onDestroy();
RefWatcher refWatcher =MyApplication.getRefWatcher(this);
refWatcher.watch(this);
}
}
原理介绍
RefWatcher.watch() 会创建一个内存泄露的观察对象[KeyedWeakReference]。在后台进程中,会检查引用对象是否被清除或者触发回收,如果没有被清除或者回收,leaks讲相关引用存储在一个.hprof的文件内。
HeapAnalyzerService 运行在一个独立的process,HeapAnalyzer用HAHA框架[一个Android heap分析框架]解析堆栈。
由于一个唯一的引用键,HeapAnalyzer在堆转储中找到KeyedWeakReference,并找到泄漏的引用。
HeapAnalyzer 计算出内存泄露的链
结果通过 DisplayLeakService打印在APP进程中显示。
1.触发检测
每次当Activity/Fragment执行完onDestroy生命周期,LeakCanary就会获取到这个Activity/Fragment,然后初始化RefWatcher对它进行分析,查看是否存在内存泄漏。
2.判断分析是否内存泄露
首先尝试着从ReferenceQueue队列中获取待分析对象(软引用和弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用或弱引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个软引用或弱引用加入到与之关联的引用队列中),如果不为空,那么说明正在被系统回收,如果直接就返回DONE,说明已经被系统回收了,如果没有被系统回收,可能存在内存泄漏,手动触发系统GC,然后再尝试移除待分析对象,如果还存在,说明存在内存泄漏。
3.分析内存泄漏
确定有内存泄漏后,调用heapDumper.dumpHeap()生成.hprof文件目录。HAHA 是一个由 square 开源的 Android 堆分析库,分析 hprof 文件生成Snapshot对象。Snapshot用以查询对象的最短引用链。找到最短引用链后,定位问题,排查代码将会事半功倍。
image.png image.png
如何解决内存泄露
为了解决内存泄露,你需要去看看使用或者引用是不是导致泄露,Leakcanary工具会抓到泄露并显示出来,可以根据相关代码检查是否内存泄露。
有相关问题可以在Stack Overflow 提问题。
总结
1.AOSP中也会存在内存泄露
2.LeakCanary对内存泄露检测有效,但是对于service泄露无法检测到
- 无法走到destory周期的内存泄露无法解决。
网友评论