面試官:說說Java物件的四種引用方式

yes的練級攻略發表於2019-05-09

我們知道在Java中除了基礎的資料型別以外,其它的都為引用型別。 而Java根據其生命週期的長短將引用型別又分為強引用、軟引用、弱引用、幻象引用

正常情況下我們平時基本上我們只用到強引用型別,而其他的引用型別我們也就在面試中,或者平日閱讀類庫或其他框架原始碼的時候才能見到。

1.強引用

我們平日裡面的用到的new了一個物件就是強引用,例如 Object obj = new Object();當JVM的記憶體空間不足時,寧願丟擲OutOfMemoryError使得程式異常終止也不願意回收具有強引用的存活著的物件

記住是存活著,不可能是你new一個物件就永遠不會被GC回收。當一個普通物件沒有其他引用關係,只要超過了引用的作用域或者顯示的將引用賦值為null時,你的物件就表明不是存活著,這樣就會可以被GC回收了。當然回收的時間是不一定的具體得看GC回收策略。

2.軟引用

軟引用的生命週期比強引用短一些。軟引用是通過SoftReference類實現的。

Object obj = new Object();
SoftReference softObj = new SoftReference(obj);
obj = null; //去除強引用
複製程式碼

這樣就是一個簡單的軟引用使用方法。通過get()方法獲取物件。當JVM認為記憶體空間不足時,就回去試圖回收軟引用指向的物件,也就是說在JVM丟擲OutOfMemoryError之前,會去清理軟引用物件。軟引用可以與引用佇列(ReferenceQueue)聯合使用。

Object obj = new Object();
ReferenceQueue queue = new ReferenceQueue();
SoftReference softObj = new SoftReference(obj,queue);
obj = null; //去除強引用
複製程式碼

softObj軟引用的obj被GC回收之後,softObj 物件就會被塞到queue中,之後我們可以通過這個佇列的poll()來檢查你關心的物件是否被回收了,如果佇列為空,就返回一個null。反之就返回軟引用物件也就是softObj

軟引用一般用來實現記憶體敏感的快取,如果有空閒記憶體就可以保留快取,當記憶體不足時就清理掉,這樣就保證使用快取的同時不會耗盡記憶體。例如圖片快取框架中快取圖片就是通過軟引用的。

3.弱引用

弱引用是通過WeakReference類實現的,它的生命週期比軟引用還要短,也是通過get()方法獲取物件。

 Object obj = new Object();
 WeakReference<Object> weakObj = new WeakReference<Object>(obj);
 obj = null; //去除強引用
複製程式碼

在GC的時候,不管記憶體空間足不足都會回收這個物件,同樣也可以配合ReferenceQueue 使用,也同樣適用於記憶體敏感的快取。ThreadLocal中的key就用到了弱引用。

4.幻象引用

也稱虛引用,是通過PhantomReference類實現的。任何時候可能被GC回收,就像沒有引用一樣。

Object obj = new Object();
ReferenceQueue queue = new ReferenceQueue();
PhantomReference<Object> phantomObj = new PhantomReference<Object>(obj , queue);
obj = null; //去除強引用
複製程式碼

無法通過虛引用訪問物件的任何屬性或者函式。那就要問了要它有什麼用?虛引用僅僅只是提供了一種確保物件被finalize以後來做某些事情的機制。比如說這個物件被回收之後發一個系統通知啊啥的。虛引用是必須配合ReferenceQueue 使用的,具體使用方法和上面提到軟引用的一樣。主要用來跟蹤物件被垃圾回收的活動。


如有錯誤歡迎指正!

個人公眾號:yes的練級攻略

有相關面試進階(分散式、效能調優、經典書籍pdf)資料等待領取

相關文章