剖析LeakCanary—— 上篇

本文详细解析了Java中的四种引用类型:强引用、软引用、弱引用和虚引用,以及它们之间的区别。同时,深入探讨了引用队列(ReferenceQueue)的使用场景和实现原理,包括其在不同JDK版本中的FIFO与LIFO实现差异,并暗示了LeakCanary内存泄漏检测工具可能的实现方式。

狭路相逢宜回身,往来都是暂时人。

1.吐槽大会

今天刚到工位上组内同事跑过来问我,What’s 引用队列? 中午吃饭闲聊时,才知道面试被问住啦。这里根据其描述,大概总结如下:

  1. Java中的四种引用类型?并简述一下其区别
  2. 平时开发中一般用到哪几种啊?(据实回答,否则分分钟打脸,同事的脸现在还是红的呢 ~2333)
  3. 了解引用队列(Reference Queue) 吗?(这都回答不出来, 面试就到这里吧…)
  4. 八成概率是要问 LeakCanary的原理?或者是 如何造一个类似LeakCanary的轮子?

听了同事的无厘头的抱怨,不得不吐槽一下,有时候专业的面试官遇到非专业的面试者,那也是秀才遇见兵啊…


1.2 面试官心里苦啊

秀才遇见兵,有理说不清啊…

试想一下,如果上来直接问你LeakCanary的原理,就算以前看过其源码的人也要思索回顾一下吧(背答案的就不提了…)。按照这位面试官的问法,答案是水到渠成。 退一步讲,如果上面3问都回答出来,就算答不出第4问,也会进一步引导并加以考虑的。(Generally speaking, 知道前3问,没有理由答不出第4问,唯一的理由:紧张)


2. Java的四种引用类型及区别

以下盗的图把Java的四种引用类型及区别都描述的很清楚啦

在这里插入图片描述

Java中的四种引用类型

在Android开发中,我们一般用到强引用弱引用(WeakReference),根据个人的实际情况即可。

3. 引用队列(ReferenceQueue)

引用队列是配合软引用弱引用虚引用一起使用的,当这些引用被GC时,就将其加入到引用队列中。

值得注意是:
官方JDK的实现是FIFO(先进先出)
OpenJDK的实现是LIFO(后进先出)

public class ReferenceQueue<T> {
    // NOTE: This implementation of ReferenceQueue is FIFO (queue-like) whereas
    // the OpenJdk implementation is LIFO (stack-like).
    private Reference<? extends T> head = null;
    private Reference<? extends T> tail = null;
  }

3.1 引用队列的使用

当我们希望在一个对象被GC时得到反馈或者进一步处理,就需要借助于引用队列

public class WeakReference<T> extends Reference<T> {

    public WeakReference(T referent) {
        super(referent);
    }
	// 注意这个构造函数:将引用放入到指定的引用队列中,我们可以对queue进行监控
    public WeakReference(T referent, ReferenceQueue<? super T> q) {
        super(referent, q);
    }
}

4. 总结

根据我们上面的描述,当弱引用软引用虚引用被回收时,这些引用将会被加入到引用队列(ReferenceQueue)中。

根据这些知识点,让我们猜测LeakCanary的实现原理 —— 借助于ReferenceQueue的状态来判断。

欢迎继续查看: 剖析LeakCanary—— 中篇

LeakCanary在检测到内存泄漏时会进行dump操作,将内存信息保存到.hprof文件中。 LeakCanary使用ObjectWatcher来监控Android的生命周期,当Activity和Fragment被销毁后,这些引用会以WeakReference的形式传递给ObjectWatcher。如果经过垃圾回收5秒后这些引用仍然存在,那么就会认为发生了内存泄漏。当泄漏的对象达到一个阈值时,LeakCanary会将Java堆栈信息dump到.hprof文件中。 然后,LeakCanary使用Shark库来解析.hprof文件,找到无法被清除的引用引用链。根据对Android系统的知识,LeakCanary判断是哪个实例导致的泄漏。最后,LeakCanary将完整的引用链缩减为一个小的引用链,并将由于这个小的引用链导致的泄漏链聚合在一起。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [leakCanary检测内存泄漏的原理](https://blog.youkuaiyun.com/qq_36639105/article/details/126171414)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [【Android 日常学习】LeakCanary——面试官最爱问的性能优化工具,你知道它是怎么工作的吗?(源码分析)](https://blog.youkuaiyun.com/qq_29966203/article/details/123943504)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值