狹路相逢宜回身,往來都是暫時人。
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—— 中篇