Android 和 Java 内存泄露检测。
在 build.gradle 中加入引用,不同的编译使用不同的引用:
dependencies {
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3'
}
在 Application 中:
public class BaseApplication extends Application {
private RefWatcher refWatcher ;
public static RefWatcher getRefWatcher(Context mContext){
BaseApplication app = (BaseApplication) mContext.getApplicationContext();
return app.refWatcher ;
}
@Override
public void onCreate() {
super.onCreate();
refWatcher = LeakCanary.install(this) ;
}
}
使用 RefWatcher 监控那些本该被回收的对象,让所有类都去继承BaseActivity,在每个Activity销毁的时候,都会去检测是否有内存问题。
public class BaseActivity extends Activity{
@Override
protected void onDestroy() {
super.onDestroy();
RefWatcher refWatcher = BaseApplication.getRefWatcher(this) ;
refWatcher.watch(this);
}
}
在 debug build 中,如果检测到某个 activity 有内存泄露,LeakCanary 就是自动地显示一个通知。
08-10 12:04:45.925 16463-17516/com.xiansen.eremis D/LeakCanary:
In com.xiansen.eremis:Moon_V2.0.0.0:2000.
* com.xiansen.eremis.activity.CheckJobWebActivity has leaked:
* GC ROOT com.android.webview.chromium.ResourcesContextWrapperFactory
WebViewContextWrapper.mBase∗referencescom.xiansen.eremis.application.BaseApplication.mComponentCallbacks∗referencesjava.util.ArrayList.array∗referencesarrayjava.lang.Object[].[2]∗referencesorg.chromium.androidwebview.AwContents
AwComponentCallbacks.this
0∗referencesorg.chromium.androidwebview.AwContents.mContext∗referencescom.android.webview.chromium.ResourcesContextWrapperFactory
WebViewContextWrapper.mBase
* leaks com.xiansen.eremis.activity.CheckJobWebActivity instance
* Reference Key: 67d05f7e-079d-49a7-bc8d-51fdc4065565
* Device: OPPO OPPO OPPO A53m A53m
* Android Version: 5.1.1 API: 22
* Durations: watch=5081ms, gc=270ms, heap dump=2097ms, analysis=17023ms
以上就是经过检测之后再Logcat中显示的内存问题。
工作机制
RefWatcher.watch() 创建一个 KeyedWeakReference 到要被监控的对象。
然后在后台线程检查引用是否被清除,如果没有,调用GC。
如果引用还是未被清除,把 heap 内存 dump 到 APP 对应的文件系统中的一个 .hprof 文件中。
在另外一个进程中的 HeapAnalyzerService 有一个 HeapAnalyzer 使用HAHA 解析这个文件。
得益于唯一的 reference key, HeapAnalyzer 找到 KeyedWeakReference,定位内存泄露。
HeapAnalyzer 计算 到 GC roots 的最短强引用路径,并确定是否是泄露。如果是的话,建立导致泄露的引用链。
引用链传递到 APP 进程中的 DisplayLeakService, 并以通知的形式展示出来。
以上就是我在简单使用时的开发心得,想了解更详细的内容,请参考:
http://www.liaohuqiu.net/cn/posts/leak-canary-read-me/
谢谢!!!