我們平常用的都是對象的強引用,如果有強引用存在,GC是不會回收對象的。我們能不能同時保持對對象的引用,而又可以讓GC需要的時候回收這個對象呢?.NET中提供了WeakReference來實現。弱引用可以讓您保持對對象的引用,同時允許GC在必要時釋放對象,回收內存。對於那些創建便宜但耗費大量內存的對象,即希望保持該對象,又要在應用程序需要時使用,同時希望GC必要時回收時,可以考慮使用弱引用。
一:什麼是弱引用
瞭解弱引用之前,先了解一下什麼是強引用
例如 : Object obj=new Object(); 就是一個強引用,內存分配一份空間給用以存儲Object數據,這塊內存有一個首地址,也就是obj所保存的數據,內存分配的空間中不僅僅保存着Object對象信息,還保存着自己(Object本身)被引用的次數。
當一個對象被強引用的形式創建的時候,本身被引用的次數已經爲1.
接着Object o=obj; 這句代碼執行之後,obj指向的Object的存儲空間已經被引用了2次,所以Object保存的被引用數值爲2.
總結:強引用最終導致的結果就是被引用的對象的被引用次數+1;
相反的弱引用就是不會對被引用對象的被引用次數有任何影響。
二:弱引用有什麼作用
防止內存泄露。
Object obj=new Object();
當你在通過異步的形式訪問網絡上面的資源的時候,需要的時間可能會比較長,在數據返回之前,用戶很可能轉向了其他的頁面,如果異步訪問的對象(obj)對本地的一個對象(Object)是強引用的話,那麼在這個異步訪問對象(obj)被釋放之前,也即在數據被回調之前,這個被引用的對象(Object)是不會被銷燬的,這樣一來,就導致內存一直被佔用。
WeakReference weakObj=new WeakReference(Object);
此時就可以使用弱引用,弱引用對象(weakObj)發出異步請求,在回調之前,如果用戶要轉到其他的頁面,這個被引用的對象(Object)是可以被釋放的,這樣子就不會出現內存一直被佔用的現象。
三:怎樣使用弱引用
弱引用類: WeakReference //有兩個重載的構造函數
WeakReference WeakObj=new WeakReference(Object); //弱引用方式
IsAlive屬性是判斷此弱引用對象所引用的對象是否還存在,存在:IsAlive=True;
Target屬性是設置該弱引用對象所引用的數據對象的值
弱引用使用起來很簡單,看下面的代碼:
Object obj = new Object();
WeakReference wref = new WeakReference( obj );
obj = null;
第一行代碼新建了一個新的對象,這裏叫它對象A,obj是對對象A的強引用。接着第二行代碼新建了一個弱引用對象,參數就是對象A的強引用,第三行代碼釋放掉對對象A的強引用。這時如果GC進行回收,對象A就會被回收。
怎樣在取得對象A的強引用呢?很簡單,請看代碼2:
Object obj2 = wref.Target;
if( obj2 != null )
{
// 做你想做的事吧。
}
else
{
// 對象已經被回收,如果要用必須新建一個。
}
只要顯示的將弱引用的Target屬性附值就會得到弱引用所代表對象的一個強引用。不過在使用對象之前要對其可用性進行檢查,因爲它可能已經被回收了。如 果你得到的是null(VB.NET下爲Nothing),表明對象已經被回收,不能再用了,需要重新分配一個。如果不是null,就可以放心大膽的用 了。