最近一直在學(xué)習(xí)LeakCanary這個庫,大神的庫果然是學(xué)習(xí)的好資料呼渣,通過這個庫學(xué)習(xí)了很多開發(fā)中學(xué)不到的知識棘伴,打算寫一系列文章對自己的學(xué)習(xí)做一個總結(jié)。
什么是LeakCanary
引用README中的介紹:
A memory leak detection library for Android and Java.
“A small leak will sink a great ship.”
-Benjamin Franklin
項目結(jié)構(gòu)
- analyzer
核心類是分析HeapAnalyzer屁置,作用是dump下來的堆內(nèi)存焊夸,驗證是否真的發(fā)生內(nèi)存溢出 - watcher
核心類是RefWatcher,作用是觀察一個對象是否被釋放缰犁。當(dāng)發(fā)現(xiàn)一個對象應(yīng)該被釋放而沒有被釋放時淳地,就會觸發(fā)HeapDump怖糊。 - android
核心module帅容,是LeakCanary的入口颇象,核心類是LeakCanary,它會創(chuàng)建RefWatcher并徘,去觀察activity的引用遣钳。 - android-no-op
跟android哪個module一樣,里面也有LeakCanary這個類麦乞,但no-op代表不會做任何操作蕴茴,用于線上版本的依賴。 - sample
square 公司給的例子
使用項目
依賴
我們可以參考sample的依賴
dependencies {
debugCompile project(':leakcanary-android')
releaseCompile project(':leakcanary-android-no-op');
}
在debug模式下姐直,引入正常版本倦淀,在release模式下引入no-op版本。
注入到項目中
public class ExampleApplication extends Application {
@Override public void onCreate() {
super.onCreate();
LeakCanary.install(this);
}
}
看看android和android-no-op的區(qū)別
android module中
public final class LeakCanary {
public static RefWatcher install(Application application) {
return install(application, DisplayLeakService.class,
AndroidExcludedRefs.createAppDefaults().build());
}
public static RefWatcher install(Application application,
Class<? extends AbstractAnalysisResultService> listenerServiceClass,
ExcludedRefs excludedRefs) {
...
RefWatcher refWatcher = androidWatcher(application, heapDumpListener, excludedRefs);
...
return refWatcher;
}
public static RefWatcher androidWatcher(Context context, HeapDump.Listener heapDumpListener,
ExcludedRefs excludedRefs) {
...
return new RefWatcher(executor, debuggerControl, GcTrigger.DEFAULT, heapDumper,
heapDumpListener, excludedRefs);
}
}
返回的RefWatcher能夠正常的監(jiān)測對象声畏。
android-no-op module中
public final class LeakCanary {
public static RefWatcher install(Application application) {
return RefWatcher.DISABLED;
}
}
public final class RefWatcher {
public static final RefWatcher DISABLED = new RefWatcher();
private RefWatcher() {
}
public void watch(Object watchedReference) {
}
public void watch(Object watchedReference, String referenceName) {
}
}
返回的RefWatcher中的watch方法都是空方法撞叽,不會監(jiān)測對象。