更多 Java 虛擬機方面的文章慕购,請參見文集《Java 虛擬機》
引用隊列 Reference Queue
Reference queues, to which registered reference objects are appended by the garbage collector after the appropriate reachability changes are detected.
引用隊列骏令,首先在引用隊列中注冊對象引用束昵,當 GC 檢測到其中的對象可達性發(fā)生改變時辛友,將該對象引用添加到引用隊列中叉谜。
ReferenceQueue
由 Reference
自身的鏈表結(jié)構(gòu)所實現(xiàn)杰捂,提供了如下方法:
-
boolean enqueue(Reference<? extends T> r)
:入列比驻,由Reference
對象調(diào)用 -
public Reference<? extends T> poll()
:出列 -
public Reference<? extends T> remove()
:刪除隊頭元素
強引用 Strong Reference
例如 String s = new String("abc");
強引用的對象不會被 GC 回收。
軟引用 Soft Reference
所在包:java.lang.ref
繼承自 Reference
:public class SoftReference<T> extends Reference<T>
軟引用的對象在內(nèi)存緊張時會被 GC 回收认轨。適合于創(chuàng)建緩存绅络。
使用步驟:
- 創(chuàng)建對象
- 用
SoftReference
封裝該對象
public static void main(String[] args) {
String s = new String("abc");
SoftReference<String> ref = new SoftReference<String>(s);
System.out.println(ref.get());
}
軟引用可以和一個引用隊列聯(lián)合使用,如果軟引用所引用的對象被垃圾回收器回收嘁字,GC 就會把這個軟引用加入到與之關(guān)聯(lián)的引用隊列中恩急。
弱引用 Weak Reference
所在包:java.lang.ref
繼承自 Reference
:public class WeakReference<T> extends Reference<T>
無論內(nèi)存是否緊張,GC 在碰到弱引用的對象時都會回收纪蜒。
使用步驟:
- 創(chuàng)建對象
- 用
SoftReference
封裝該對象衷恭,注冊到ReferenceQueue
public static void main(String[] args) throws Exception {
ReferenceQueue<String> queue = new ReferenceQueue<String>();
String s = new String("abc");
WeakReference<String> ref = new WeakReference<String>(s, queue);
System.out.println(queue.poll()); // null
s = null; // 將引用設(shè)為 null
System.gc(); // 執(zhí)行 GC, 當GC 檢測到其中的對象可達性發(fā)生改變時纯续,將該對象引用添加到引用隊列中
Thread.sleep(1000);
System.out.println(queue.poll()); // 從引用隊列中讀出
}
輸出:
null
java.lang.ref.WeakReference@1540e19d
弱引用的使用場景:集合類随珠。例如 WeakHashMap
:
An entry in a WeakHashMap will automatically be removed when its key is no longer in ordinary use. More precisely, the presence of a mapping for a given key will not prevent the key from being discarded by the garbage collector, that is, made finalizable, finalized, and then reclaimed. When a key has been discarded its entry is effectively removed from the map, so this class behaves somewhat differently from other Map implementations.
WeakHashMap 中的元素 Entry,當它的 key 不再使用時杆烁,Entry 會被自動刪除牙丽。
更準確地說,即使某個 key 仍然在 WeakHashMap 中兔魂,這個 key 還是會被 GC 回收,當 key 被回收后举娩,它對應的整個 Entry 就會從 WeakHashMap 中刪除析校。
示例:
// HashMap 中對 key 是強引用
HashMap<Integer, String> map = new HashMap<Integer, String>();
Integer it1 = new Integer(1);
map.put(it1, "A");
// WeakHashMap 中對 key 是弱引用
WeakHashMap<Integer, String> weakHap = new WeakHashMap<Integer, String>();
Integer it2 = new Integer(1);
weakHap.put(it2, "A");
// 將 key 對象設(shè)為不可達狀態(tài)
it1 = null;
it2 = null;
// 掃描所有對象构罗,檢查是否可達狀態(tài)
System.gc();
Thread.sleep(1000);
System.out.println(map.get(1)); // 輸出 A
System.out.println(weakHap.get(1)); // 輸出 null
虛引用 Phantom Reference
所在包:java.lang.ref
繼承自 Reference
:public class PhantomReference<T> extends Reference<T>
虛引用的對象在任何時候都可能被垃圾回收器回收。
虛引用不能單獨使用智玻,需要放在一個 ReferenceQueue
中遂唧,用于追蹤對象被 GC 回收的情況。