強引用、軟引用、弱引用、虛引用 · 語雀 (yuque.com) 自 JDK1.2 開始,Java 提供了 4 種引用關係,以表示引用和實例對象的關係。 強引用“一直存活著” 強引用,就是我們最常見的普通對象引用。 只要強引用還存在,垃圾收集器永遠不會回收掉被引用的實例對象。 Object o = ...
強引用、軟引用、弱引用、虛引用 · 語雀 (yuque.com)
自 JDK1.2 開始,Java 提供了 4 種引用關係,以表示引用和實例對象的關係。
強引用“一直存活著”
強引用,就是我們最常見的普通對象引用。
只要強引用還存在,垃圾收集器永遠不會回收掉被引用的實例對象。
Object o = new Object();
軟引用“有 n 次活的機會”
在系統將要發生記憶體溢出異常之前,垃圾收集器會把只被軟引用關聯著的實例對象進行回收,如果這次回收還沒有足夠的記憶體,才會拋出記憶體溢出異常(OutOfMemoryError)。
軟引用通常用來實現記憶體敏感的緩存:
- 如果還有空閑記憶體,就可以暫時保留緩存;
- 如果記憶體不足,則清理掉緩存;
這樣就保證了使用緩存的同時,不會耗盡記憶體。
SoftReference<Object> softO = new SoftReference<>(new Object());
弱引用“回收就會死亡”
被弱引用關聯著的實例對象只能生存到下一次垃圾收集發生之前,當垃圾收集器工作時,無論當前記憶體是否足夠,都會回收掉只被弱引用關聯的實例對象。
弱引用可以用來構建一種沒有特定約束的關係,比如,維護一種非強制性的映射關係,如果試圖獲取時對象還在,就使用它,否則重現實例化。弱引用同樣是很多緩存實現的選擇。
WeakReference<Object> weakO = new WeakReference(new Object());
虛引用“隨時可能被回收”
虛引用也稱為“幽靈引用”或者“幻影引用”,虛引用是最弱的一種引用關係。
- 在Java 8以及之前的版本中,在虛引用回收後,虛引用指向的對象才會回收。
- 在Java 9以及更新的版本中,虛引用不會對對象的生存時間產生任何影響。
無法通過虛引用來獲取一個實例對象。
虛引用主要用來跟蹤對象被垃圾回收的活動,回收對象關聯的資源。
在Java 8以及之前的版本中,當垃圾收集器準備回收一個實例對象時,如果發現它還有虛引用,就會在回收實例對象之前,把這個虛引用加入到與之關聯的引用隊列中。程式如果發現某個虛引用已經被加入到引用隊列,那麼就可以在所引用的對象的記憶體被回收之前採取必要的行動,然後斷開虛引用對象的引用,虛引用被回收或者不可達,虛引用指向的對象才會回收。
Object counter = new Object();
ReferenceQueue refQueue = new ReferenceQueue<>();
PhantomReference<Object> p = new PhantomReference<>(counter, refQueue);
counter = null;
System.gc();
try {
// Remove 是一個阻塞方法,可以指定 timeout,或者選擇一直阻塞
Reference<Object> ref = refQueue.remove(1000L);
if (ref != null) {
// do something
ref = null;
}
} catch (InterruptedException e) {
// Handle it
}
參考資料
本文來自博客園,作者:真正的飛魚,轉載請註明原文鏈接:https://www.cnblogs.com/feiyu2/p/reference.html