在Java 1.2中就引入了java.lang.ref這個包,WeakReference就屬於這個包。WeakReference是幹嘛的呢,一言弊之,它是和Java中的記憶體回收相關的。如果一個對象只有WeakReference引用它,那麼這個對象就可能被記憶體回收行程回收。
在什麼場合下應用WeakReference呢?
(1) 有時我們會碰到一些不能繼承的類,如final class,無法繼承它。假如我們要使用一個Widget類,因為某種緣故無法繼承該類來加入某個功能。但是,我們必須將每個Widget對象和某個序號關聯,而Widget本身沒有serial number這個屬性,這時該怎麼做呢?
你也許已經想到,用HashMap:serialNumberMap.put(widget, widgetSerialNumber);這看起來工作的很好。但是有個問題:當我們不再需要某個Widget的serial number資訊,此時應該從HashMap中將這個Entry移除,如果我們忘記了怎麼辦?因為HashMap中持有對這個對象的引用,這個對象永遠不會被記憶體回收行程回收,這就造成了記憶體流失!這意味著我們需要像沒有記憶體回收功能的語言一樣,手動管理記憶體!但是我們用的是Java。
(2)另一個很常見的問題是緩衝。如果使用強引用,那麼我們緩衝的對象就會一直滯留在記憶體中,不會被回收,除非我們手動的將其從緩衝中移除。此外,這還需要我們決定何時從緩衝中移除對象,又一個手動管理記憶體的問題!此時,WeakReference就顯示出它的價值了。如何建立一個WeakReference呢?
WeakReference<widget> weakWidget = newWeakReference<widget>(widget);Widget w = weakWidget.get();
要注意的是,當調用weakReference.get()可能返回null(意味著指向的對象已經被回收)。其實,對於Widget serial number這個問題,最簡單的方法是使用WeakHashMap,它的使用和普通的HashMap完全一樣,不同點在於,WeakHashMap的key被實現為一種WeakReference(注意,是key而不是value),當key對象被回收後,WeakHashMap會自動將對應的entry移除。更精確的說,對於一個給定的鍵,其映射的存在並不阻止記憶體回收行程對該鍵的回收。
(3)Java中有四種類型的引用,按照強弱關係依次為:Strong Reference>Soft Reference>WeakReference> Phantom Reference。其中,我們平常用的就是Strong Reference,而Phantom Reference很少用到,那麼什麼是Soft Reference呢?
Soft Reference和weak reference的區別是:一旦gc發現對象是weak reference可達就會把它放到ReferenceQueue中,然後等下次gc時回收它;當對象是Soft reference可達時,gc可能會向作業系統申請更多記憶體,而不是直接回收它,當實在沒轍了才回收它。像cache系統,最適合用Soft reference。讓gc來替我們決定什麼時候回收對象以及回收哪些對象。差別範例如下:WeakReference的模型
A obj = new A();
WeakReference wr = new WeakReference(obj);
obj = null;
//等待一段時間,obj對象就會被記憶體回收
...
if (wr.get()==null)
{
System.out.println("obj 已經被清除了 ");
} else {
System.out.println("obj 尚未被清除,其資訊是 "+obj.toString());
}
參考原文:http://blog.csdn.net/ponderforever/article/details/7299069
參考原文:http://wenku.baidu.com/view/8c04b0d249649b6648d74786.html