[.NET] WeakReference的使用

聲明:本篇博客翻譯自:http://tipsandtricks.runicsoft.com/CSharp/WeakReferences.htmlhtml

因爲水平(技術水平+英語理解能力)有限/不足,確定會有所疏漏/錯誤,請及時指正。性能

在平常開發中,一般會遇到一些大對象的處理。這些大對象一般在整個程序中屢次使用。例如:大文件對象,大的字典類。一般狀況下咱們會使用下面的方式:spa

做爲一個方法的內置本地變量;翻譯

做爲一個類的字段存在;code

這兩種方式都不是很好。做爲一個類的字段,類的實例將一直持有這個大對象,消耗不少內存;做爲一個方法的本地變量使用,當方法執行完畢,這個大對象離開了做用域,但此時不必定會被GC直接回收。形成沒必要要的內存消耗。且每次調用該方法時,會從新建立新的大對象,增長程序的內存消耗。htm

若是建立對象很消耗資源,且咱們想要避免屢次建立同一個對象。可使用類的字段方式。對象

一般狀況下,當一個對象離開了做用域,或者被設置爲null。咱們將沒法訪問到它。.NET提供了一個WeakReference類,能夠完美的解決這個問題。blog

WeakReference對象將保存一個對象的引用即便這個對象已經離開了做用域或者被設置爲null了,經過WeakReference還能夠訪問到這個對象。除非被GC回收掉了,WeakReference對象此時沒法訪問到該對象。ip

WeakReference的使用很是簡單,內存

MyHugeObject hugeObject = new MyHugeObject();
WeakReference w new WeakReference(hugeObject);

經過WeakReference的Target屬性能夠得到關聯的對象,

MyHugeObject = w.Target as MyHugeClass;

若是這個對象仍然存在,經過Target屬性能夠得到到。若是對象已經被GC回收了,Target獲得的值爲null

static void Func()
{
    MyHugeClass MyHugeObject;            
    if ( (w == null) || ( (MyHugeObject=w.Target as MyHugeClass) == null) )
    {
        MyHugeObject new MyHugeClass();
        w new WeakReference(MyHugeObject);
    }
    // work with MyHugeObject             
}

WeakReference提供給咱們很大的好處:它將保持MyHugeObject的引用,而且確保能夠在沒有被GC回收的狀況下從新獲得該對象,且不用擔憂從新得到的對象是不完整的或者被損壞的。

PS:使用WeakReference並不能保證提升程序的性能,大多數狀況下相比於使用本地局部變量而言性能會有所提升。可是不作任何擔保。一些狀況下還會出現更多的程序性能消耗,例如一個大對象關聯了許多小對象,此時會將這些小對象也轉成Weak Reference。此時會對GC內存回收有損耗。

參考連接:

https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/weak-references

http://tipsandtricks.runicsoft.com/CSharp/WeakReferences.html

https://msdn.microsoft.com/en-us/library/system.weakreference(v=vs.110).aspx

相關文章
相關標籤/搜索