詳聊Java的四種引用型別

青山梓地發表於2020-11-03

最近,在回顧關於JVM的相關知識,其中有一個比較簡單,同時又容易被大家忽視的知識點,就是關於4種引用的定義與使用場景,其實仔細刨析原始碼的時候會發現,在Java中很多地方都有涉及到關於不同引用的問題,並且有些面試官也會在面試的時候問及到這一塊的內容,所以小編就根據自己的學習,總結了一下這部分的知識點,希望可以與大家一起學習,如果有錯誤或者不足的地方,歡迎大家在評論區裡指摘。

這四種引用,由高到低依次為:強引用、軟引用、弱引用、虛引用。

  • 強引用(StrongReference)

強引用是目前為止在Java中使用最多的一種引用,那麼什麼才是強引用呢,最簡單的一種就是 A a = new A();這種a就屬於一種強引用,如果一個物件是強引用的,那就意味著,它一直處於可達狀態,那怕記憶體不足,垃圾回收器都無法回收這部分物件。所以強引用也是造成Java記憶體洩露的一個重要原因,往往在迴圈中創造出大量的強引用的物件,最終導致OOM。

  • 軟引用(SoftReference)

如果一個物件只具有軟引用,在記憶體空間夠用的時候,垃圾回收器不會回收它,可以被繼續使用,但是在記憶體空間不足的時候,這些物件的記憶體就會被回收掉,以騰出足夠的空間,因此,在很多情況下,軟引用可以被用來實現記憶體敏感的快取記憶體,示例如下:

想要實現一個客戶資訊查詢時,大部分的都是第一次從資料庫中讀取資訊放入記憶體中,後續相同查詢時,直接從記憶體中返回資料,提高響應速度,但是這樣做有個問題,那就是記憶體空間會被一直佔據,如果後面訪問很少,那麼這部分記憶體空間就浪費了,如果多次類似操作出現的話,最終將會導致記憶體溢位錯誤。

  • 弱引用(WeakReference)

想解釋好弱引用,直接將其與軟引用比較來看,則更為清晰,弱引用與軟引用的區別:只具有弱引用的物件,擁有更為短暫的生命週期,在GC執行緒掃描到它所在的記憶體區域的時候,一旦發現了只有弱引用的物件的時候,不管記憶體夠不夠用都會將其回收掉,而軟引用則如上所說的,只有記憶體不足的時候才會進行回收。PS:垃圾回收器執行緒是一個優先順序很低的執行緒,所以很多時候並不會立刻就發現了只具有弱引用的物件。

  • 虛引用(PhantomReference)

“虛”引用,顧名思義,這種引用形同虛設,而且這種引用並不會決定著物件的生命週期,因為一個物件僅僅持有虛引用,那麼就可以將它看作沒有引用的物件,根據垃圾回收機制可知,對於一個沒有任何引用的物件,則視為無用物件,隨時都會被回收掉。那麼問題來了,那這種引用有什麼用呢?其實這種虛引用主要是用來跟蹤物件被垃圾回收活動的,並且它必須要和引用佇列(ReferenceQueue)聯合使用。當垃圾回收器準備回收一個物件的時候,如果發現它還有一個虛引用,就會在回收物件的記憶體之前,把這個虛引用放入到與之關聯的引用佇列中。程式碼如下:

ReferenceQueue rq = new ReferenceQueue();

PhantomReference pr = new PhantomReference(object,queue);

面試考點!!!

問題1:若一個物件的引用型別有多個,那到底如何判斷它的可達性呢?

  答:1:單條引用鏈的可達性以最弱的一個引用型別來決定;

         2:多條引用鏈的可達性以最強的一個引用型別來決定;

相關文章