LeakCanary1.5代码流程分析

LeakCanary 使用

在Application的onCreate中,如下操作

 if (LeakCanary.isInAnalyzerProcess(this)) {
            // This process is dedicated to LeakCanary for heap analysis.
            // You should not init your app in this process.
            return;
        }
        LeakCanary.install(this);
        // Normal app init code...

1.LeakCanary.isInAnalyzerProcess(this)

判断当前进程是否和HeapAnalyzerService在同一进程

 * Whether the current process is the process running the {@link HeapAnalyzerService}, which is
   * a different process than the normal app process.
   */
  public static boolean isInAnalyzerProcess(Context context) {
    return isInServiceProcess(context, HeapAnalyzerService.class);
  }

2.LeakCanary.install(this);

public static RefWatcher install(Application application) {
    return refWatcher(application).listenerServiceClass(DisplayLeakService.class)
        .excludedRefs(AndroidExcludedRefs.createAppDefaults().build())
        .buildAndInstall();
  }
refWatcher(application)

返回一个AndroidRefWatcherBuilder对象 AndroidRefWatcherBuilder extends RefWatcherBuilder

/** Builder to create a customized {@link RefWatcher} with appropriate Android defaults. */
  public static AndroidRefWatcherBuilder refWatcher(Context context) {
    return new AndroidRefWatcherBuilder(context);
  }

以下均在AndroidRefWatcherBuilder.java中

.listenerServiceClass(DisplayLeakService.class)

  /**
   * Sets a custom {@link AbstractAnalysisResultService} to listen to analysis results. This
   * overrides any call to {@link #heapDumpListener(HeapDump.Listener)}.
   */
  public AndroidRefWatcherBuilder listenerServiceClass(
      Class listenerServiceClass) {
    return heapDumpListener(new ServiceHeapDumpListener(context, listenerServiceClass));
  }

  • DisplayLeakService extends AbstractAnalysisResultService extends IntentService 用于展示leak之后的dump信息
  • 创建ServiceHeapDumpListener对象 作为heapDumpListener

2..excludedRefs(AndroidExcludedRefs.createAppDefaults().build())

ExcludedRefs排除的引用?
AndroidExcludedRefs.createAppDefaults().build() 创建一个ExcludedRefs对象给RefWatcherBuilder

 /**
   * This returns the references in the leak path that can be ignored for app developers. This
   * doesn't mean there is no memory leak, to the contrary. However, some leaks are caused by bugs
   * in AOSP or manufacturer forks of AOSP. In such cases, there is very little we can do as app
   * developers except by resorting to serious hacks, so we remove the noise caused by those leaks.
   */
  public static ExcludedRefs.Builder createAppDefaults() {
    return createBuilder(EnumSet.allOf(AndroidExcludedRefs.class));
  }

3 .buildAndInstall();

  /**
   * Creates a {@link RefWatcher} instance and starts watching activity references (on ICS+).
   */
  public RefWatcher buildAndInstall() {
    RefWatcher refWatcher = build();
    if (refWatcher != DISABLED) {
      LeakCanary.enableDisplayLeakActivity(context);
      ActivityRefWatcher.install((Application) context, refWatcher);
    }
    return refWatcher;
  }
  • 创建RefWatcher对象
  • enableDisplayLeakActivity(context)
  • ActivityRefWatcher.install((Application) context, refWatcher)

enableDisplayLeakActivity(context)

 public static void enableDisplayLeakActivity(Context context) {
    setEnabled(context, DisplayLeakActivity.class, true);
  }

DisplayLeakActivity用于展示dump的Activity

  public static void setEnabled(Context context, final Class componentClass,
      final boolean enabled) {
    final Context appContext = context.getApplicationContext();
    executeOnFileIoThread(new Runnable() {
      @Override public void run() {
        setEnabledBlocking(appContext, componentClass, enabled);
      }
    });
  }

executeOnFileIoThread

  public static void executeOnFileIoThread(Runnable runnable) {
    fileIoExecutor.execute(runnable);
  }

private static final Executor fileIoExecutor = newSingleThreadExecutor("File-IO");
是一个单线程线程池在执行setEnabledBlocking(),冻结应用

 public static void setEnabledBlocking(Context appContext, Class componentClass,
      boolean enabled) {
    ComponentName component = new ComponentName(appContext, componentClass);
    PackageManager packageManager = appContext.getPackageManager();
    int newState = enabled ? COMPONENT_ENABLED_STATE_ENABLED : COMPONENT_ENABLED_STATE_DISABLED;
    // Blocks on IPC.
    packageManager.setComponentEnabledSetting(component, newState, DONT_KILL_APP);
  }

Android 应用冻结流程分析

ActivityRefWatcher.install((Application) context, refWatcher)

public static void install(Application application, RefWatcher refWatcher) {
    new ActivityRefWatcher(application, refWatcher).watchActivities();
  }

ActivityRefWatcher#watchActivities()

ActivityRefWatcher.java

  public void watchActivities() {
    // Make sure you don't get installed twice.
    stopWatchingActivities(); //避免重复install
    application.registerActivityLifecycleCallbacks(lifecycleCallbacks);
  }

application.registerActivityLifecycleCallbacks(lifecycleCallbacks);

lifecycleCallbacks为ActivityRefWatcher中的成员变量,值得注意的是

ActivityRefWatcher.java

   @Override public void onActivityDestroyed(Activity activity) {
          ActivityRefWatcher.this.onActivityDestroyed(activity);
        }

继续跟代码

 void onActivityDestroyed(Activity activity) {
    refWatcher.watch(activity);
  }

RefWatcher.java

 public void watch(Object watchedReference) {
    watch(watchedReference, "");
  }
  public void watch(Object watchedReference, String referenceName) {
    if (this == DISABLED) {
      return;
    }
    checkNotNull(watchedReference, "watchedReference");
    checkNotNull(referenceName, "referenceName");
    final long watchStartNanoTime = System.nanoTime();
    String key = UUID.randomUUID().toString();
    retainedKeys.add(key);
    final KeyedWeakReference reference =
        new KeyedWeakReference(watchedReference, key, referenceName, queue);//1

    ensureGoneAsync(watchStartNanoTime, reference);//2
  }
final KeyedWeakReference reference =new KeyedWeakReference(watchedReference, key, referenceName, queue)

KeyedWeakReference继承弱引用,构造器传入watchedReference、referenceName,key。watchedReference是监视destory的Activity对象,referenceName = "",key为随机生成

System.nanoTime()返回的是纳秒,nanoTime而返回的可能是任意时间,甚至可能是负数

ensureGoneAsync(watchStartNanoTime, reference)
 private void ensureGoneAsync(final long watchStartNanoTime, final KeyedWeakReference reference) {
    watchExecutor.execute(new Retryable() {
      @Override public Retryable.Result run() {
        return ensureGone(reference, watchStartNanoTime);
      }
    });
  }
watchExecutor

watchExecutor由RefWatcher构造函数传入

RefWatcherBuilder.java

build()

 public final RefWatcher build() {
  
    WatchExecutor watchExecutor = this.watchExecutor;
    if (watchExecutor == null) {
      watchExecutor = defaultWatchExecutor();
    }

    return new RefWatcher(watchExecutor, debuggerControl, gcTrigger, heapDumper, heapDumpListener,
        excludedRefs);
  }

watchExecutor()

  /** @see WatchExecutor */
  public final T watchExecutor(WatchExecutor watchExecutor) {
    this.watchExecutor = watchExecutor;
    return self();
  }

AndroidRefWatcherBuilder.java

 public AndroidRefWatcherBuilder watchDelay(long delay, TimeUnit unit) {
    return watchExecutor(new AndroidWatchExecutor(unit.toMillis(delay)));
  }
 @Override protected WatchExecutor defaultWatchExecutor() {
    return new AndroidWatchExecutor(DEFAULT_WATCH_DELAY_MILLIS);
  }

watchExecutor对象是一个AndroidWatchExecutor,DEFAULT_WATCH_DELAY_MILLIS = 5s

AndroidWatchExecutor.java

@Override public void execute(Retryable retryable) {
    if (Looper.getMainLooper().getThread() == Thread.currentThread()) {
      waitForIdle(retryable, 0);
    } else {
      postWaitForIdle(retryable, 0);
    }
  }

如果在主线程

ensureGone(reference, watchStartNanoTime)

  • 两次 removeWeaklyReachableReferences()
  • gcTrigger.runGc()
  • heapdumpListener.analyze()
 @SuppressWarnings("ReferenceEquality") // Explicitly checking for named null.
  Retryable.Result ensureGone(final KeyedWeakReference reference, final long watchStartNanoTime) {
    long gcStartNanoTime = System.nanoTime();
    long watchDurationMs = NANOSECONDS.toMillis(gcStartNanoTime - watchStartNanoTime);

    removeWeaklyReachableReferences();

    if (debuggerControl.isDebuggerAttached()) {
      // The debugger can create false leaks.
      return RETRY;
    }
    if (gone(reference)) {
      return DONE;
    }
    gcTrigger.runGc();
    removeWeaklyReachableReferences();
    if (!gone(reference)) {
      long startDumpHeap = System.nanoTime();
      long gcDurationMs = NANOSECONDS.toMillis(startDumpHeap - gcStartNanoTime);

      File heapDumpFile = heapDumper.dumpHeap();
      if (heapDumpFile == RETRY_LATER) {
        // Could not dump the heap.
        return RETRY;
      }
      long heapDumpDurationMs = NANOSECONDS.toMillis(System.nanoTime() - startDumpHeap);
      heapdumpListener.analyze(
          new HeapDump(heapDumpFile, reference.key, reference.name, excludedRefs, watchDurationMs,
              gcDurationMs, heapDumpDurationMs));
    }
    return DONE;
  }

removeWeaklyReachableReferences()


  private void removeWeaklyReachableReferences() {
    // WeakReferences are enqueued as soon as the object to which they point to becomes weakly
    // reachable. This is before finalization or garbage collection has actually happened.
    KeyedWeakReference ref;
    while ((ref = (KeyedWeakReference) queue.poll()) != null) {
      retainedKeys.remove(ref.key);
    }
  }

gcTrigger.runGc()

public void runGc() {

      // System.gc() does not garbage collect every time. Runtime.gc() is
      // more likely to perfom a gc.
      Runtime.getRuntime().gc();
      enqueueReferences();
      System.runFinalization();
    }

ServiceHeapDumpListener.java

@Override public void analyze(HeapDump heapDump) {
    checkNotNull(heapDump, "heapDump");
    HeapAnalyzerService.runAnalysis(context, heapDump, listenerServiceClass);
  }

RefWatcher其实就是一个引用观察者对象,是用于监测当前实例对象的引用状态的

你可能感兴趣的:(LeakCanary1.5代码流程分析)