在Application中初始化
LeakCanary.install(this);
使用build設(shè)計(jì)模式危号,創(chuàng)建RefWatcher對象
public static @NonNull RefWatcher install(@NonNull Application application) {
return refWatcher(application).listenerServiceClass(DisplayLeakService.class)
.excludedRefs(AndroidExcludedRefs.createAppDefaults().build())
.buildAndInstall();
}
設(shè)置heap監(jiān)聽 ServiceHeapDumpListener
public @NonNull AndroidRefWatcherBuilder listenerServiceClass(
@NonNull Class<? extends AbstractAnalysisResultService> listenerServiceClass) {
enableDisplayLeakActivity = DisplayLeakService.class.isAssignableFrom(listenerServiceClass);
return heapDumpListener(new ServiceHeapDumpListener(context, listenerServiceClass));
}
public @NonNull RefWatcher buildAndInstall() {
if (LeakCanaryInternals.installedRefWatcher != null) {
throw new UnsupportedOperationException("buildAndInstall() should only be called once.");
}
RefWatcher refWatcher = build();
if (refWatcher != DISABLED) {
if (enableDisplayLeakActivity) {
LeakCanaryInternals.setEnabledAsync(context, DisplayLeakActivity.class, true);
}
//觀察activity
if (watchActivities) {
ActivityRefWatcher.install(context, refWatcher);
}
//觀察fragment
if (watchFragments) {
FragmentRefWatcher.Helper.install(context, refWatcher);
}
}
LeakCanaryInternals.installedRefWatcher = refWatcher;
return refWatcher;
}
在ActivityRefWatcher 中,處理activity引用觀察情況
//觀察activity
public static void install(@NonNull Context context, @NonNull RefWatcher refWatcher) {
Application application = (Application) context.getApplicationContext();
//創(chuàng)建activity引用觀察類
ActivityRefWatcher activityRefWatcher = new ActivityRefWatcher(application, refWatcher);
//activity生命周期回調(diào)
application.registerActivityLifecycleCallbacks(activityRefWatcher.lifecycleCallbacks);
}
接下來看activity回調(diào)
private final Application.ActivityLifecycleCallbacks lifecycleCallbacks =
new ActivityLifecycleCallbacksAdapter() {
@Override public void onActivityDestroyed(Activity activity) {
//在onDestroy中添加觀察
refWatcher.watch(activity);
}
};
調(diào)用RefWatcher中 watch
public void watch(Object watchedReference, String referenceName) {
...
final long watchStartNanoTime = System.nanoTime();
String key = UUID.randomUUID().toString();
//保存一個(gè)隨機(jī)key扫步,用于判斷當(dāng)前對象是否被回收
retainedKeys.add(key);
//把a(bǔ)ctivity放到弱引用池中
final KeyedWeakReference reference =
new KeyedWeakReference(watchedReference, key, referenceName, queue);
ensureGoneAsync(watchStartNanoTime, reference);
}
RefWatcher.ensureGoneAsync方法中會調(diào)用ensureGone(reference, watchStartNanoTime); 所以接下來看這個(gè)方法
Retryable.Result ensureGone(final KeyedWeakReference reference, final long watchStartNanoTime) {
long gcStartNanoTime = System.nanoTime();
long watchDurationMs = NANOSECONDS.toMillis(gcStartNanoTime - watchStartNanoTime);
//移除引用池中key
removeWeaklyReachableReferences();
if (debuggerControl.isDebuggerAttached()) {
// The debugger can create false leaks.
return RETRY;
}
//判斷此引用是否還存在
if (gone(reference)) {
return DONE;
}
//出發(fā)gc
gcTrigger.runGc();
//再次移除
removeWeaklyReachableReferences();
//此引用還存在妻顶,說明此引用還未回收酸员,存在內(nèi)存泄漏的風(fēng)險(xiǎn)
if (!gone(reference)) {
long startDumpHeap = System.nanoTime();
long gcDurationMs = NANOSECONDS.toMillis(startDumpHeap - gcStartNanoTime);
//生成hprof文件 AndroidHeapDumper 文件路徑 File downloadsDirectory = Environment.getExternalStoragePublicDirectory(DIRECTORY_DOWNLOADS);
//Debug.dumpHprofData(heapDumpFile.getAbsolutePath());
File heapDumpFile = heapDumper.dumpHeap();
if (heapDumpFile == RETRY_LATER) {
// Could not dump the heap.
return RETRY;
}
long heapDumpDurationMs = NANOSECONDS.toMillis(System.nanoTime() - startDumpHeap);
HeapDump heapDump = heapDumpBuilder.heapDumpFile(heapDumpFile).referenceKey(reference.key)
.referenceName(reference.name)
.watchDurationMs(watchDurationMs)
.gcDurationMs(gcDurationMs)
.heapDumpDurationMs(heapDumpDurationMs)
.build();
//堆內(nèi)存分析
heapdumpListener.analyze(heapDump);
}
return DONE;
}
ServiceHeapDumpListener 中analyze方法會調(diào)用 HeapAnalyzerService.runAnalysis(context, heapDump, listenerServiceClass); 創(chuàng)建一個(gè)服務(wù)HeapAnalyzerService來分析
public static void runAnalysis(Context context, HeapDump heapDump,
Class<? extends AbstractAnalysisResultService> listenerServiceClass) {
setEnabledBlocking(context, HeapAnalyzerService.class, true);
setEnabledBlocking(context, listenerServiceClass, true);
Intent intent = new Intent(context, HeapAnalyzerService.class);
intent.putExtra(LISTENER_CLASS_EXTRA, listenerServiceClass.getName());
intent.putExtra(HEAPDUMP_EXTRA, heapDump);
ContextCompat.startForegroundService(context, intent);
}
//在onHandleIntent調(diào)用
@Override protected void onHandleIntentInForeground(@Nullable Intent intent) {
...
String listenerClassName = intent.getStringExtra(LISTENER_CLASS_EXTRA);
HeapDump heapDump = (HeapDump) intent.getSerializableExtra(HEAPDUMP_EXTRA);
//核心類蜒车,堆內(nèi)存
HeapAnalyzer heapAnalyzer =
new HeapAnalyzer(heapDump.excludedRefs, this, heapDump.reachabilityInspectorClasses);
AnalysisResult result = heapAnalyzer.checkForLeak(heapDump.heapDumpFile, heapDump.referenceKey,
heapDump.computeRetainedHeapSize);
AbstractAnalysisResultService.sendResultToListener(this, listenerClassName, heapDump, result);
}