0
点赞
收藏
分享

微信扫一扫

谈谈 LeakCanary 原理 --标准答案

承蒙不弃 2021-09-19 阅读 91
  1. 内存泄漏
    传统意义上的内存泄漏是至忘记手动释放内存,导致未释放的内存不可使用的现象。

  2. jvm 的内存泄漏
    jvm的内存泄漏指的是我们本不再需要的内存,躲过了垃圾回收的现象。
    android中的内存泄漏指的是 短生命周期的对象被长生命周期的对象所持有,导致无法进行垃圾回收的现象。

  3. 如何判断一个对象不再使用
    引用计数法:优点是简单高效,缺点是会有循环引用的问题。
    可达性分析:

  4. 当一个Activity被回收时,会执行 finalize()。可以通过finalize()是否执行判断Activity是否被回收。

  5. 手动 gc Runtime.getRuntime().gc()

  6. GC 回收机制与分代回收策略
    https://juejin.cn/post/6891589544161116168

具体流程

  1. LeakCanary 在注册了一个AndroidLifecyleCallback,在每一个Activity执行完onDestory后对Activity进行监视。监视的核心方法是RefWatcher.watch()。在watch方法中将需要观察的对象进行了包装,创建了一个WeakReference的对象。

  2. 将引用检查的任务通过Looper.myQueue().addIdleHandler添加到MessageQueue中,在主线程空闲的时候进行引用检查操作。

  3. 具体的检查操作是循环检查弱引用的返回是否为空,以及检查与弱引用相关的队列,如果弱引用被回收了,引用相关的WeakReference就会被加入到队列中。使用这个方式检查内存泄漏。

String str = "hello";    // 强引用
str = null;              // 取消强引用
SoftReference<String> softName = new  SoftReference<>("haha");
WeakReference<String> weakName = new WeakReference<String>("hello");
WeakReference(T referent, ReferenceQueue<? super T> q)
ReferenceQueue<String> queue = new ReferenceQueue<String>();
PhantomReference<String> pr = new PhantomReference<String>(new String("hello"), queue);
举报

相关推荐

0 条评论