美文网首页android进阶
leakcanary源码分析

leakcanary源码分析

作者: Liuqc | 来源:发表于2019-12-19 21:22 被阅读0次

    在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);
    }
    

    相关文章

      网友评论

        本文标题:leakcanary源码分析

        本文链接:https://www.haomeiwen.com/subject/avmvnctx.html