狭路相逢宜回身,往来都是暂时人。
1.吐槽大会
今天刚到工位上组内同事跑过来问我,What’s 引用队列? 中午吃饭闲聊时,才知道面试被问住啦。这里根据其描述,大概总结如下:
- Java中的四种引用类型?并简述一下其区别?
- 平时开发中一般用到哪几种啊?(据实回答,否则分分钟打脸,同事的脸现在还是红的呢 ~2333)
- 了解**引用队列(Reference Queue)**吗?(这都回答不出来, 面试就到这里吧…)
- 八成概率是要问 LeakCanary的原理?或者是 如何造一个类似LeakCanary的轮子?
听了同事的无厘头的抱怨,不得不吐槽一下,有时候专业的面试官遇到非专业的面试者,那也是秀才遇见兵啊…
1.2 面试官心里苦啊
秀才遇见兵,有理说不清啊…
试想一下,如果上来直接问你LeakCanary的原理,就算以前看过其源码的人也要思索回顾一下吧(背答案的就不提了…)。按照这位面试官的问法,答案是水到渠成。 退一步讲,如果上面3问都回答出来,就算答不出第4问,也会进一步引导并加以考虑的。(Generally speaking, 知道前3问,没有理由答不出第4问,唯一的理由:紧张)
2. 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—— 中篇