垃圾回收(四)【弱引用】

風靈使發表於2019-01-08

如果應用程式的程式碼可以訪問一個正由該程式使用的物件,垃圾回收器就不能回收該物件, 那麼,就認為應用程式對該物件具有強引用。

弱引用允許應用程式訪問物件,同時也允許垃圾回收器收集相應的物件。 如果不存在強引用,則弱引用的有限期只限於收集物件前的一個不確定的時間段。 使用弱引用時,應用程式仍可對該物件進行強引用,這樣做可防止該物件被收集。 但始終存在這樣的風險:垃圾回收器在重新建立強引用之前先處理該物件。

佔用大量記憶體,但通過垃圾回收功能回收以後很容易重新建立的物件特別適合使用弱引用。

假設 Windows 窗體應用中的樹狀檢視向使用者顯示層次結構複雜的選項。 如果基礎資料量很大,則使用者使用應用程式中的其他部分時,在記憶體中保留該樹會導致效率低下。

當使用者切換到應用的其他部分時,可以使用WeakReference 類建立對樹的弱引用,並銷燬所有強引用。 當使用者切換回該樹時,應用程式會嘗試獲得對該樹的強引用,如果成功,就不必重新構造該樹。

若要對某物件建立弱引用,請使用要跟蹤的物件例項建立 WeakReference。 然後將 Target 屬性設定為該物件,將該物件的原始引用設定為 null。 有關程式碼示例,請參閱類庫中的 WeakReference

短弱引用和長弱引用

可以建立短弱引用或長弱引用:

  • Short
    垃圾回收功能回收物件後,短弱引用的目標會變為 null。 弱引用本身是託管物件,與其他任何託管物件一樣需要經過垃圾回收。 短弱引用是 WeakReference 的預設建構函式。
  • Long
    在物件的 Finalize
    方法已呼叫後,長弱引用獲得保留。 這樣,便可以重新建立該物件,但該物件仍保持不可預知的狀態。 若要使用長引用,請在WeakReference 建構函式中指定 true
    如果物件型別不包含 Finalize 方法,應用的是短弱引用功能。弱引用只在目標被收集前有效,執行終結器後可以隨時收集目標。

若要建立強引用並重新使用物件,請將 WeakReferenceTarget 屬性強制轉換為物件型別。 如果 Target 屬性返回 null,表示物件已被收集;否則,可繼續使用物件,因為應用已重新獲得對它的強引用。

使用弱引用的準則

僅在必要時使用長弱引用,因為在終結後物件的狀態不可預知。

避免對小物件使用弱引用,因為指標本身可能和物件一樣大,或者比物件還大。

避免將弱引用作為記憶體管理問題的自動解決方案, 而應開發一個有效的快取策略來處理應用程式的物件。

相關文章