【乾貨點】看完該篇文章,就基本能夠解答面試熱點【談談對Java中幾種引用的理解】了。面試
你們都知道我公衆號的副業是算法
因此常常會有朋友找我吹水,最近就說到了一個面試題數據庫
談談對Java中幾種引用的理解。編程
所以打算以該面試題爲例子,寫篇文章說說在Java中引用是什麼以及怎麼用。 【劃重點:給你三秒鐘時間思考,若是是你,該如何回答面試官的這個問題呢】數組
【劃重點】在Java中引用包括:安全
那麼爲何會提供這四種引用呢,主要緣由有:cdn
學以至用,那麼這幾個引用在平常中咱們如何進行使用呢? 接下來我會給出相關demo!!!對象
相似於 Object o = new Object() 這類的引用,建立一個對象後,該引用會被保存在JVM棧中,並且只要強引用存在,垃圾回收器就不會回收掉被引用的對象。blog
平常使用生命週期
強引用的例子比比皆是,由於在平常開發中咱們是會常常去new一個對象的,而該new出來的對象即是強引用的,也就是說只要該引用存在,垃圾回收器就不會回收掉。 【劃重點:JVM怎麼知道引用在不在?】
軟引用關聯的對象,在內存不夠的狀況下,會把這些軟引用關聯的對象列入垃圾回收範圍中,而後進行回收,也就是說軟引用並不是是徹底安全的,在內存不夠的狀況下是會被垃圾回收器回收掉的。
給出demo
經過註釋即可以知道,我這裏實例化了多個大對象,而後放入softReferences數組中,以後便遍歷打印出其中的對象的命名,打印結果以下
能夠經過結果看出,前面四個對象由於內存不夠而被垃圾回收器回收了。
平常使用
在我司的項目中,部分是使用軟引用來保存從數據庫中取出的數據,具體是作了一箇中間層的封裝,該中間層的做用就是在get出數據的時候會去判斷數據是否爲null,若是是爲null再次從數據庫讀取,讀取後再放入軟引用的集合中,這樣的作法是能夠避免內存溢出。
弱引用比軟引用更弱,被弱引用關聯的對象只能存活到發生下一次垃圾回收以前,也就是說當發生GC時,不管當前內存是否足夠,都會被回收掉。
給出demo
代碼很簡短,就是先構建一個弱引用對象,而後在gc前先打印出來證實它存在過,以後手動調用gc,再次打印,能夠看出已經沒了。運行結果以下
虛引用和上面不一樣的地方在於,一個對象是否有虛引用的存在,徹底不會對其生存時間構成如何影響,而且也沒法經過虛引用來獲取一個對象的實例,也就是說跟沒有引用與之關聯同樣,在任什麼時候候均可能被垃圾回收器回收。
那麼這樣就很容易產生疑問了,虛引用的做用又是什麼呢?
做用就是能在這個對象被收集器回收時收到一個系統通知,實現追蹤垃圾收集器的回收動做,好比在對象被回收的時候,會調用該對象的finalize方法。
在給出相關demo前,要先介紹一個
ReferenceQueue 引用隊列
ReferenceQueue 引用其實也能夠概括爲引用中的一員,能夠和上述三種引用類型組合使用【軟引用、弱引用、虛引用】。
那麼它有何做呢?
在建立Reference時,手動將Queue註冊到Reference中,而當該Reference所引用的對象被垃圾收集器回收時,JVM會將該Reference放到該隊列中,而咱們即可以對該隊列作些其餘業務,至關於一種通知機制。
給出demo
能夠從demo中看出隊列的用法,運行打印結果以下
咱們能夠從結果中看到先是從引用中get出來的對象爲null,證實上面說的沒法經過虛引用來獲取一個對象的實例,而且在回收後會被放入隊列中。
首先爲了方便JVM進行管理,Reference是有狀態的,能夠分爲如下四種狀態
關於JVM怎麼知道引用在不在,這就涉及到了JVM的可達性分析算法了 JVM的可達性分析算法的簡單思路就是經過一系列GC Roots做爲出發點,向下搜索,搜索所走過的路徑稱爲引用鏈,當一個對象到GC Roots沒有任何引用鏈,即代表從GC Roots到這個對象不可達時,證實此對象不可用,可被回收。以下圖所示
對象四、五、6都是可被回收的。 那麼問題來了,哪些對象能夠做爲GC Roots呢? 這裏給出幾個,以下
虛擬機棧中引用的對象
方法區中類靜態屬性引用的對象
方法區中常量引用的對象
本地方法棧JNI引用的對象
具體的想要深刻研究的能夠自行百度&谷歌,或者等我後面深刻分析。
該篇文章基本解答了【談談對Java中幾種引用的理解】,若是想要更深刻的研究,就要從源碼入手瞭解了。 下次碰見這種面試題,基本上就不慌了,由於實際上只要認真看完該篇文章而且記住幾個關鍵的地方,基本上就不會被面試官問倒了,而且該篇文章後面也解答了【JVM怎麼知道引用在不在】和【哪些對象能夠做爲GC Roots】的問題。
公衆號主營:服務端編程相關技術解說,具體能夠看歷史文章。
公衆號副業:各類陪聊吹水,包括技術、就業、人生經歷、大學生活、內推等等。
歡迎關注,一塊兒侃大山