Pages

2016-03-27

了解Weak Reference弱式參考

NET程序的變數(Variable)指向一個Object記憶體,這塊記憶體會在該變數的存活期間一直保存,直到變數離開視野才被GC(Garbage Collector)標記及回收,此種變數與記憶體的參考關係,稱為Strong Reference (強式參考)。ASP.NET裏有一個Cache Collection,它是隨著Web App的生命周期一直存活著,但其集合項目所指向的記憶體久佔不放,因此我們希望能在一個Wek Reference的參考關係,即讓該參考變數一直存活,但其指向的記憶體項目能因為系統GC的回收而自然被釋放。

下圖是WeakReference類別提供的簡單範例,建構子指向一個Target Object記憶體,當GC.Collect()後,該Target Object會變成null, 且IsAlive=False。然而若在GC前有讀取過該Target記憶體(第11行),第15行的結果卻是IsAlive=True。若整段Code貼到一個for loop視野內,Target存活的狀況又變得不一樣了,這些涉及到GC的回收機制(Generation)及適用策略而變得不可預測,所以官方文件裏都會告訴你WeakReference指向的Target記憶體存活狀況不可靠,儘量不要用。

WeakReference Declare

然而有些資料不是那麼重要,而且也無法預知它的內容何時會被釋放,不如就用GC自由掃射,只要我們存取變數值時安全檢查一下就好。以下就是一個簡單的Cache Dictionary集合實作範例:
Cache Dictionary

WeakReference項目GC回收的時機點很難預測,我們該怎麼安全地讀值呢?簡單地說,就是比對一下項目Target值 是否為null值就好,而異動集合項目時配合lock{}也可來達到ThreadSafe。

Dictionary ReadValue
因為讀值需要判斷一堆的,所以新式的ASP.NET Caching內部實作時間Expire存活機制,讓集合的項目 能明確保存一段時間,這會是更好的管理方式。

No comments: