要观察一个对象是否泄漏,通过调用RefWatcher的watch方法,会创建一个KeyedWeakReference,并关联一个refenceQueue:
public void watch(Object watchedReference, String referenceName) {
......
String key = UUID.randomUUID().toString();
retainedKeys.add(key);
final KeyedWeakReference reference =
new KeyedWeakReference(watchedReference, key, referenceName, queue);
watchExecutor.execute(new Runnable() {
@Override public void run() {
ensureGone(reference, watchStartNanoTime);
}
});
}
在ensureGone里
void ensureGone(KeyedWeakReference reference, long watchStartNanoTime) {
....
removeWeaklyReachableReferences();
if (gone(reference) || debuggerControl.isDebuggerAttached()) {
return;
}
gcTrigger.runGc();
removeWeaklyReachableReferences();
if (!gone(reference)) {
long startDumpHeap = System.nanoTime();
long gcDurationMs = NANOSECONDS.toMillis(startDumpHeap - gcStartNanoTime);
File heapDumpFile = heapDumper.dumpHeap();
if (heapDumpFile == HeapDumper.NO_DUMP) {
// Could not dump the heap, abort.
return;
}
long heapDumpDurationMs = NANOSECONDS.toMillis(System.nanoTime() - startDumpHeap);
heapdumpListener.analyze(
new HeapDump(heapDumpFile, reference.key, reference.name, excludedRefs, watchDurationMs,
gcDurationMs, heapDumpDurationMs));
}
}
检查keyedweakreference是否被回收,如果被回收,返回,如果没被回收,触发一次gc,然后再次检查是否被回收,如果没被回收,说明是有泄漏了,做一次heapdump进行分析。
在heapdump中查找keyedweakreference,然后看keyedWeakreference的key是否与生成heapdump的key相同,然后分析leak 的最短路径。
从leakcanary的源代码中可以看出,gc root的类型