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

C# 內存管理深度解析(十):靜態變量線程安全、單例模式與總結

     編輯:關於C語言

靜態變量線程安全問題


class Counter
{
    private static int _count = 0;
    public static int GetNext()
    {
        int n = _count;
        // 模擬耗時操作
        _count = n + 1;
        return n;
    }
}
// 多線程並發調用 GetNext() 會導致返回值重複/丟失

鎖定解決方案


class Counter
{
    private static int _count = 0;
    private static readonly object _lock = new object();
    public static int GetNext()
    {
        lock (_lock)
        {
            int n = _count;
            _count = n + 1;
            return n;
        }
    }
}
// 或使用 Interlocked.Increment(ref _count) 無鎖原子操作

引用類型靜態字段的 GC 影響


class Olympics
{
    public static List Runners = new List();
}
class Runner
{
    public FileStream Stream; // 未關閉的非托管資源
}
// 靜態列表持有 Runner → Runner 不會被 GC 回收 → FileStream 洩漏

教訓:靜態字段是 GC Root,會長期存活引用對象,必須及時清理非托管資源(實現 IDisposable、使用 using)。

單例模式最佳實踐


// 推薦:靜態只讀字段 + 私有構造函數(CLR 保證線程安全初始化)
public sealed class Earth
{
    private static readonly Earth _instance = new Earth();
    private Earth() { }
    public static Earth Instance => _instance;
}

// 雙重檢查鎖(舊版 .NET 可能需要 volatile,現代 .NET 不再推薦)
// 避免:嵌套類延遲初始化、Lazy<T>(除非構造極其昂貴)

總結:高性能內存管理十大原則

  1. 及時釋放非托管資源:using / IDisposable / SafeHandle。
  2. 減少不必要引用:用完置 null,特別是事件處理器、大對象、靜態集合。
  3. 慎用終結器:優先 IDisposable;終結器增加 GC 壓力、延遲回收、順序不定。
  4. 對象圖局部性:相關對象集中分配(如數組、List),減少堆碎片,提升 GC 掃描效率。
  5. 避免大對象堆 (LOH) 碎片:>85KB 對象進 LOH,複用緩衝區、使用 ArrayPool。
  6. 值類型優先:小型、不可變數據用 struct,減少堆分配與 GC 掃描。
  7. 字符串拼接用 StringBuilder:避免大量臨時字符串對象。
  8. 事件取消訂閱:-= 防止發布者持有訂閱者導致內存洩漏。
  9. 弱引用緩存:WeakReference / ConditionalWeakTable 實現可回收緩存。
  10. 分析工具:dotMemory、PerfView、GC.GetTotalMemory 定期檢視堆狀態。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved