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

CLR 記憶體配置與垃圾回收機制深度解析

     編輯:關於C#

托管堆配置機制

  • 新物件配置:new 指令在托管堆上指標前移配置,**極快** (僅指標運算),連續記憶體有利 CPU 快取。
  • 第 0 代 (Gen 0):新建物件預設配置於 Gen 0,空間小 (約 256KB~幾 MB),回收頻繁、速度極快。
  • 大物件堆 (LOH):≥ 85,000 位元組物件直接配置於 LOH,**不壓縮**、僅 Gen 2 回收時處理,易產生碎片。

垃圾回收 (GC) 觸發條件

  1. Gen 0 空間不足配置新物件。
  2. 呼叫 GC.Collect() (生產環境**極少**主動呼叫)。
  3. 系統記憶體壓力大 (Windows 通知 CLR)。

回收演算法:標記-壓縮

  1. 標記階段:從 GC Roots (靜態欄位、執行緒堆疊區域變數、CPU 寄存器、Finalize 佇列物件) 向下遍歷,標記所有**可達**物件。
  2. 壓縮階段:將可達物件向堆底部移動,消除空洞,更新所有參考指標;不可達物件記憶體自動釋放。
  3. 代際假設:年輕物件死得快、老物件活得久。Gen 0/1 回收頻繁且快;Gen 2 (含 LOH) 回收較慢,頻率低。

Finalize / 析構函式與 Dispose 模式


public class ResourceHolder : IDisposable
{
    private IntPtr _unmanagedHandle;
    private bool _disposed;

    public ResourceHolder() => _unmanagedHandle = AcquireUnmanagedResource();

    // 公開 Dispose (供呼叫端主動釋放)
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this); // 告訴 GC 不需呼叫 Finalize
    }

    // 受保護虛擬方法 (供衍生類別覆寫)
    protected virtual void Dispose(bool disposing)
    {
        if (_disposed) return;
        if (disposing)
        {
            // 釋放託管資源 (其他 IDisposable 物件)
        }
        // 釋放非託管資源
        ReleaseUnmanagedResource(_unmanagedHandle);
        _unmanagedHandle = IntPtr.Zero;
        _disposed = true;
    }

    // Finalize (析構函式) - 保障未呼叫 Dispose 時仍能釋放非託管資源
    ~ResourceHolder() => Dispose(false);
}

關鍵差異比較

特性Finalize (~)Dispose()
呼叫時機GC 回收時 (非決定性)呼叫端決定 (決定性)
效能影響物件需進入 Finalization Queue,**至少經過 2 次 GC** 才釋放記憶體立即釋放資源,GC 正常回收記憶體
適用資源僅非託管資源保障託管 + 非託管資源
執行緒Finalizer 專用執行緒呼叫端執行緒

效能優化建議

  1. 避免不必要的 Finalize:未持有非託管資源的類別**不要**寫析構函式。
  2. 實作 IDisposable:持有非託管資源或託管資源 (Stream, DbConnection, Timer 等) 必須實作。
  3. 使用 using / await using:確保決定性釋放,即使發生例外。
  4. 大物件 (<85KB) 複用:使用 ArrayPool<T>.Shared、MemoryPool<T> 減少 LOH 壓力。
  5. 避免 Gen 2 物件短命:長期存活的大型集合、快取物件會推高 Gen 2 回收成本。
  6. 弱參考:快取場景可用 WeakReference<T> 允許 GC 回收。

GC 設定 (較少調整)

  • <gcServer enabled="true"/>:伺服器模式 (多執行緒並行 GC),適合高吞吐服務。
  • <gcConcurrent enabled="true"/>:背景 GC (預設開啟),減少暫停時間。
  • GC.LatencyMode = GCLatencyMode.SustainedLowLatency:關鍵路徑暫時降低延遲 (慎用)。

理解 GC 運作原理,配合 IDisposable 模式與物件池化,即能編寫高效能、低延遲的 .NET 應用程式。

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