LeakCanary(3)自定义DisplayLeakService

序、慢慢来才是最快的方法。

LeakCanary系列

LeakCanary(1)前传

LeakCanary(2)正文

背景


LeakCanary是Square的开源库,通过弱引用方式侦查Activity或Fragment对象的生命周期,若发现内存泄漏自动 dump Hprof文件,通过HAHA库得到泄露的最短路径,最后通过Notification展示。

简单说就是在在Activity对象onDestory的时候,新建一个WeakReference对象指向Activity对象,如果Activity对象被垃圾回收的话,WeakReference对象就会进入引用序列的ReferenceQueue。

所以我们只需要在Activity对象OnDestory之后去查看ReferenceQueue序列是否有该WeakReference对象即可。

第一次观察是Activity的onDestory5秒后,如果发现ReferenceQueue对来还没有WeakReference对象,就进入第二次观察,如果有了,就证明没有泄漏,第二次观察跟第一次观察相比区别在于会先进行垃圾回收,在进行ReferenceQueue序列的观察。
 

问题

LeakCanary只能用在测试阶段,但是我们都知道,线上才是我们真正的战场。接下来简单分析一下如果自定义LeakCanary做一个线上的内存检测。继承DisplayLeakService类,重写afterDefaultHandling()方法,实现自己的内存泄漏信息保存。

1.在初始化的时候,构建者传入的DisplayLeakService就是分析内存泄漏的地方

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

2.继承DisplayLeakService

class WanAndroidLeakService extends DisplayLeakService {

    @Override
    protected void afterDefaultHandling(HeapDump heapDump, AnalysisResult result, String leakInfo) {
        super.afterDefaultHandling(heapDump, result, leakInfo);

     //拿到内存泄露的分析结果
        boolean leakFound = result.leakFound;
        boolean excludedLeak = result.excludedLeak;
        String className = result.className;
        LeakTrace leakTrace = result.leakTrace;
        Throwable failure = result.failure;
        long retainedHeapSize = result.retainedHeapSize;
        long analysisDurationMs = result.analysisDurationMs;



    }
}

为什么不能用于线上

  • 每次内存泄漏以后,都会生成一个.hprof文件,然后解析,并将结果写入.hprof.result。增加手机负担,引起手机卡顿等问题。
  • 多次调用GC,可能会对线上性能产生影响
  • 同样的泄漏问题,会重复生成 .hprof 文件,重复分析并写入磁盘。
  • .hprof文件较大,信息回捞成问题。

尝试一下解决方案

  • 可以根据手机信息来设定一个内存阈值 M ,当已使用内存小于 M 时,如果此时有内存泄漏,只将泄漏对象的信息放入内存当中保存,不生成.hprof文件。当已使用大于 M 时,生成.hprof文件
  • 当引用链路相同时,可根据实际情况去重。
  • 不直接回捞.hprof文件,可以选择回捞分析的结果
  • 可以尝试将已泄漏对象存储在数据库中,一个用户同一个泄漏只检测一次,减少对用户的影响

参考

Android 开源库 #7 为什么各大厂自研的内存泄漏检测框架都要参考 LeakCanary?因为它是真强啊!

被问到:如何检测线上内存泄漏,通过 LeakCanary 探究!
快手KOOM高性能线上解决方案

04 | 内存优化(下):内存优化这件事,应该从哪里着手?

你可能感兴趣的:(LeakCanary)