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

C# 建構函式與解構函式深度解析(二):解構函式與垃圾回收機制

     編輯:關於C語言

三、解構函式與垃圾回收器在 C# 中的運作

什麼是解構函式?

解構函式(Destructor)是實現銷毀類別實例的方法成員。其特徵如下:

  • 無參數、無修飾符(public/private 等)
  • 無法被手動呼叫
  • 命名規則:類別名前加波浪號 ~(如 ~MyClass())
  • 用途:釋放非受控資源(Unmanaged Resources)

為什麼有了垃圾回收器(GC)還需要解構函式?

.NET CLR 提供自動記憶體管理,大多數情況下資源釋放由 GC 自動完成。但 GC 只負責管理受控堆積(Managed Heap)上的物件,對於非受控資源(如檔案控制代碼、資料庫連線、COM 物件、視窗控制代碼等),GC 無法自動釋放,必須由開發者在解構函式中撰寫釋放邏輯。

值類型 vs 參考類型的記憶體行為

類型儲存位置生命週期管理
值類型(int、struct 等)堆疊離開作用域自動釋放,不需 GC
參考類型的「參考變數」堆疊離開作用域自動釋放參考本身
參考類型的「物件實例」受控堆積由 GC 追蹤與回收

關鍵觀念:GC 僅對「堆積上的物件實例」起作用。堆疊上的變數(無論值類型或參考變數)在離開作用域時即自動釋放。

解構函式的執行機制與效能代價

  1. 物件擁有解構函式時,GC 不會立即回收,而是將其放入 Finalization Queue(完成佇列)
  2. 專用的 Finalizer 執行緒執行解構函式
  3. 解構函式執行完成後,物件才會在下一次 GC 週期中被真正回收

效能影響:擁有解構函式的物件需要「兩次 GC 週期」才能被回收,開銷遠大於無解構函式的物件。因此:

如果類別未使用非受控資源,絕對不要定義解構函式。

解構函式實作範例

public class ResourceHolder
{
    // 假設這裡持有非受控資源(如 IntPtr handle)
    
    ~ResourceHolder()
    {
        // 這裡撰寫釋放非受控資源的程式碼
        // 例如:CloseHandle(handle); 釋放檔案控制代碼
    }
}

四、總結

建構函式與解構函式雖形式簡單,但其背後涉及 CLR 記憶體管理核心機制。正確理解與使用它們,能幫助你:

  • 深入掌握 CLR 記憶體管理運作原理
  • 有效管理系統資源,避免記憶體洩漏
  • 在效能與資源釋放間取得平衡

補充:CLR(Common Language Runtime)簡介

CLR 是 .NET 的執行環境,相當於 Java 的 JVM。核心職責:

  • 記憶體管理(配置與垃圾回收)
  • 程式碼執行監控(型別安全、陣列邊界檢查、防止存取未配置記憶體)
  • 提供受控執行環境:受控代碼在 CLR 監管下執行,非受控代碼直接在作業系統上執行
  • 支援跨語言整合、例外處理、安全性驗證等

CLR 監控常見程式錯誤:陣列越界、存取未配置記憶體、資料過大導致記憶體溢位等,大幅提升平台可靠性。

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