作家
登录

带你学开源项目:LeakCanary-如何检测 Activity 是否泄漏

作者: 来源: 2017-05-24 10:06:09 阅读 我要评论

return new RefWatcher(executor, debuggerControl, GcTrigger.DEFAULT, heapDumper, 
  •       heapDumpListener, excludedRefs); 
  •  
  • 这琅绫擎涉及到两个新的对象: AndroidHeapDumper 和 AndroidWatchExecutor ,前者用来 dump 堆内存状况的,后者则是用来 watch 一个引用的监听器。具体道理后面再看。总之,这里已经生成好了一个 RefWatcher 对象了。

    如今再看膳绫擎>

  • private final Set<String> retainedKeys;public void watch(Object activity, String referenceName) { 
  •   String key = UUID.randomUUID().toString(); 
  •   retainedKeys.add(key);  final KeyedWeakReference reference =      new KeyedWeakReference(activity, key, referenceName, queue); 
  •  
  •   watchExecutor.execute(new Runnable() {    @Override public void run() { 
  •       ensureGone(reference, watchStartNanoTime); 
  •     } 
  •   }); 
  • }final class KeyedWeakReference extends WeakReference<Object> {  public final String key;  public final String name
  •  
  • 可以看到,它起首把我们传入的 activity 包装成了一个 KeyedWeakReference (可以临时算作一个通俗的 WeakReference),然后 watchExecutor 会去履行一个 Runnable,这个 Runnable 会调用 ensureGone(reference, watchStartNanoTime) 函数。

    看这个函数之前猜测下,我们知道 watch 函数本身就是用来监听 activity 是否被正常收受接收,这就涉及到两个问题:

    1. 何时去检查它是否收受接收?
    2. 若何有效地检查它真的被收受接收?

    所以我们认为 ensureGone 函数本身要做的事正如它的名字,就是确保 reference 被收受接收掉落了,不然就意味着内存泄漏。

    核心函数:ensureGone(reference) 检测收受接收

    下面来看这个函数实现:

    这里先来解释锫 WeakReference 和 ReferenceQueue 的工作道理。

       1.弱引用 WeakReference

     被强引用的对象就算产生 OOM 也永远不会被垃圾收受接收机收受接收;被弱引用的对象,只要被垃圾收受接收器发明就会急速被收受接收;被软引用的对象,具备内存敏感性,只有内存不足时才会被收受接收,常用来做内存敏感缓存器;虚引用则随便率性时刻都可能被收受接收,应用较少。

       2.引用队列 ReferenceQueue

    我们常用一个 WeakReference<Activity> reference = new WeakReference(activity); ,这里我们创建了一个 reference 明天将来引用到某个 activity ,当这个 activity 被垃圾收受接收器收受接收后,这个 reference 会被放入内部的 ReferenceQueue 中。也就是说,大年夜队列 ReferenceQueue 掏出来的所有 reference ,它们指向的┞锋实对象都已经成功被收受接收了。

    在一个 activity 传给 RefWatcher 时会创建一个独一的 key 对应这个 activity,该key存入一个集合 retainedKeys 中。也就是说,所有我们想要不雅测的 activity 对应的独一 key 都邑被放入 retainedKeys 集合中。

    基于我们对 ReferenceQueue 的懂得,只要把队列中所有的 reference 掏出来,并把对应 retainedKeys 里的key移除,剩下的 key 对应的对象都没有被收受接收。

    1. ensureGone 起首调用 removeWeaklyReachableReferences 把已被收受接收的对象的 key 大年夜 retainedKeys 移除,剩下的 key 都是未被收受接收的对象;
    2. if (gone(reference)) 用来断定某个 reference 的key是否仍在 retainedKeys 里,若不在,表示已收受接收,不然持续;
    3. gcTrigger.runGc(); 手动出发 GC,急速把所有 WeakReference 引用的对象收受接收;
    4. removeWeaklyReachableReferences(); 再次清理 retainedKeys,如不雅该 reference 还在 retainedKeys里 (if (!gone(reference))),表示泄漏;
    5. 应用 heapDumper 把内存情况 dump 成文件,并调用 heapdumpListener 进行内存分析,进一步确认是否产生内存泄漏。
    6. 如不雅确认产生内存泄漏,调用 DisplayLeakService 发送通知。

    内存泄漏检测小结

    大年夜膳绫擎我们大年夜概懂得了内存泄漏检测机制,大年夜概是以下几个步调:


      推荐阅读

      一个可以查看Linux当前缓存了哪些大文件的小工具

    Linux 用户可能经常碰到的一个问题是,机械有 16GB 内存之多,运行的过程也不多,然则剩下的 free 内存并不多,大年夜部分都被 buff 和 cache 占用了(比如下面我的 PC)。$ free -h >>>详细阅读


    本文标题:带你学开源项目:LeakCanary-如何检测 Activity 是否泄漏

    地址:http://www.17bianji.com/lsqh/35385.html

    关键词: 探索发现

    乐购科技部分新闻及文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与乐购科技进行文章共享合作。

    网友点评
    自媒体专栏

    评论

    热度

    精彩导读
    栏目ID=71的表不存在(操作类型=0)