Java Reference
在 jdk 1.2 及其以後,引入了強引用、軟引用、弱引用、虛引用這四個概念。網上很多關於這四個概念的解釋,但大多是概念性的泛泛而談,今天我結合著程式碼分析了一下,首先我們先來看定義與大概解釋(引用型別在包 java.lang.ref 裡)。
1、強引用(StrongReference)
強引用不會被GC回收,並且在java.lang.ref裡也沒有實際的對應型別。舉個例子來說:
Object obj = new Object();
這裡的obj引用便是一個強引用,不會被GC回收。
2、軟引用(SoftReference)
軟引用在JVM報告記憶體不足的時候才會被GC回收,否則不會回收,正是由於這種特性軟引用在caching和pooling中用處廣泛。軟引用的用法:
1 2 3 4 |
Object
obj = new Object();
SoftReference<Object>
softRef = new SoftReference(obj);
//
使用 softRef.get() 獲取軟引用所引用的物件
Object
objg = softRef.get();
|
3、弱引用(WeakReference)
當GC一但發現了弱引用物件,將會釋放WeakReference所引用的物件。弱引用使用方法與軟引用類似,但回收策略不同。
4、虛引用(PhantomReference)
當GC一但發現了虛引用物件,將會將PhantomReference物件插入ReferenceQueue佇列,而此時PhantomReference所指向的物件並沒有被GC回收,而是要等到ReferenceQueue被你真正的處理後才會被回收。虛引用的用法:
1 2 3 4 5 6 7 8 9 |
Object
obj = new Object();
ReferenceQueue<Object>
refQueue = new ReferenceQueue<Object>();
PhantomReference<Object>
phanRef = new PhantomReference<Object>(obj,
refQueue);
//
呼叫phanRef.get()不管在什麼情況下會一直返回null
Object
objg = phanRef.get();
//
如果obj被置為null,當GC發現了虛引用,GC會將phanRef插入進我們之前建立時傳入的refQueue佇列
//
注意,此時phanRef所引用的obj物件,並沒有被GC回收,在我們顯式地呼叫refQueue.poll返回phanRef之後
//
當GC第二次發現虛引用,而此時JVM將phanRef插入到refQueue會插入失敗,此時GC才會對obj進行回收
Reference<? extends Object>
phanRefP = refQueue.poll();
|
看了簡單的定義之後,我們結合著程式碼來測試一下,強引用就不用說了,軟引用的描述也很清楚,關鍵是 “弱引用” 與 “虛引用”。
弱引用:
1 2 3 4 5 6 7 8 9 10 11 |
public static void main(String[]
args) throws InterruptedException
{
Object
obj = new Object();
ReferenceQueue<Object>
refQueue = new ReferenceQueue<Object>();
|