要觀察一個對象是否泄漏逾滥,通過調(diào)用RefWatcher的watch方法酣倾,會創(chuàng)建一個KeyedWeakReference诅炉,并關(guān)聯(lián)一個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是否被回收箩帚,如果被回收夺艰,返回,如果沒被回收富寿,觸發(fā)一次gc睬隶,然后再次檢查是否被回收,如果沒被回收页徐,說明是有泄漏了苏潜,做一次heapdump進行分析。
在heapdump中查找keyedweakreference变勇,然后看keyedWeakreference的key是否與生成heapdump的key相同恤左,然后分析leak 的最短路徑。
從leakcanary的源代碼中可以看出搀绣,gc root的類型