LeakCanary原理

要观察一个对象是否泄漏,通过调用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的类型

LeakCanary原理_第1张图片
Paste_Image.png

你可能感兴趣的:(LeakCanary原理)