leakcanary源码分析
2019-12-19 本文已影响0人
Liuqc
在Application中初始化
LeakCanary.install(this);
使用build设计模式,创建RefWatcher对象
public static @NonNull RefWatcher install(@NonNull Application application) {
return refWatcher(application).listenerServiceClass(DisplayLeakService.class)
.excludedRefs(AndroidExcludedRefs.createAppDefaults().build())
.buildAndInstall();
}
设置heap监听 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();
//创建activity引用观察类
ActivityRefWatcher activityRefWatcher = new ActivityRefWatcher(application, refWatcher);
//activity生命周期回调
application.registerActivityLifecycleCallbacks(activityRefWatcher.lifecycleCallbacks);
}
接下来看activity回调
private final Application.ActivityLifecycleCallbacks lifecycleCallbacks =
new ActivityLifecycleCallbacksAdapter() {
@Override public void onActivityDestroyed(Activity activity) {
//在onDestroy中添加观察
refWatcher.watch(activity);
}
};
调用RefWatcher中 watch
public void watch(Object watchedReference, String referenceName) {
...
final long watchStartNanoTime = System.nanoTime();
String key = UUID.randomUUID().toString();
//保存一个随机key,用于判断当前对象是否被回收
retainedKeys.add(key);
//把activity放到弱引用池中
final KeyedWeakReference reference =
new KeyedWeakReference(watchedReference, key, referenceName, queue);
ensureGoneAsync(watchStartNanoTime, reference);
}
RefWatcher.ensureGoneAsync方法中会调用ensureGone(reference, watchStartNanoTime); 所以接下来看这个方法
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;
}
//出发gc
gcTrigger.runGc();
//再次移除
removeWeaklyReachableReferences();
//此引用还存在,说明此引用还未回收,存在内存泄漏的风险
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();
//堆内存分析
heapdumpListener.analyze(heapDump);
}
return DONE;
}
ServiceHeapDumpListener 中analyze方法会调用 HeapAnalyzerService.runAnalysis(context, heapDump, listenerServiceClass); 创建一个服务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调用
@Override protected void onHandleIntentInForeground(@Nullable Intent intent) {
...
String listenerClassName = intent.getStringExtra(LISTENER_CLASS_EXTRA);
HeapDump heapDump = (HeapDump) intent.getSerializableExtra(HEAPDUMP_EXTRA);
//核心类,堆内存
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);
}