首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

.NET Discovery 系列之四:深入理解 .NET 垃圾收集機制(下)— Dispose、GC.Collect、Finalize、WeakReference 實戰

     編輯:關於.NET

承接上篇 GC 運作模式,深入解析四大關鍵主題與實務模式。

1. Dispose() 模式:釋放非託管資源標準作法

  • 實作 IDisposable,釋放託管與非託管資源。
  • 基類實作 IDisposable 時,衍生類必須 override Dispose(bool) 並呼叫 base.Dispose(disposing)。
  • using 編譯後等同 try-finally,離開區塊自動呼叫 Dispose()(IL 驗證完全一致)。

2. GC.Collect():慎用

  • 顯式呼叫會強制 Full GC,含標記、壓縮、修正指標,極度消耗 CPU。
  • GC 由「策略引擎」根據回收效率動態調整頻率;人為干擾會誤導引擎降低自動 GC 頻率,反而降低效能。
  • 原則:空間換時間(快取),非 時間換空間(強制 GC)。CPU 比記憶體貴。
  • 例外:明確掌握大量短期物件產生時機(如批次處理結束)可考慮呼叫。

3. Finalize (解構函數) 與物件復活

  • 僅釋放非託管資源,不可觸碰託管資源(順序不可預測、可能已被回收)。
  • 含 Finalize 物件需 兩次 GC 才能回收:
    1. 首次 GC:從 Finalization Queue 移至 Freachable Queue(物件復活),執行 Finalize。
    2. 二次 GC:Finalization Queue 已無記錄,正式回收。
    • GC.SuppressFinalize(this) 用於 Dispose() 中,避免重複清理成本。
    • GC.ReRegisterForFinalize 可重新註冊 Finalize(罕用)。

    標準 Dispose/Finalize 雙重保險模式

    public class Resource : IDisposable {
        bool disposed = false;
        public void Dispose() { Dispose(true); GC.SuppressFinalize(this); }
        protected virtual void Dispose(bool disposing) {
            if (!disposed) {
                if (disposing) { /* 釋放託管資源 */ }
                /* 釋放非託管資源 */
                disposed = true;
            }
        }
        ~Resource() { Dispose(false); }
    }
    

    4. WeakReference:大物件快取利器

    • 不阻礙 GC 回收,記憶體緊張時自動釋放;未被回收前可重用。
    • WeakReference.IsAlive 檢查存活;Target 取得強參考。
    • 短弱參考 (預設):Finalize 後追蹤結束;長弱參考:Finalize 後仍追蹤(不建議干擾 GC 成果)。
    var so = new SomeObject();
    var wr = new WeakReference(so);
    so = null;
    GC.Collect();
    Console.WriteLine(wr.IsAlive); // False (已被回收)
    

    建議大物件快取採用短弱參考,平衡記憶體與重建成本。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved