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

Windows Forms 中 ActiveX 控制項無法被 GC 回收問題分析與 Windbg 除錯

     編輯:關於ASP.NET

Form 加入 ActiveX 控制項 (如 axCalendar) 後,顯式 Dispose()、設為 null 仍無法被 GC 回收,原因在於非受控資源參考殘留。

問題重現程式碼

private void button1_Click(object sender, EventArgs e) {
    this.Controls.Remove(this.axCalendar1);
    WeakReference wr = new WeakReference(this.axCalendar1, false);
    axCalendar1.Dispose();
    axCalendar1 = null;
    int i = 0;
    while (wr.IsAlive) {
        i++; GC.Collect(); MessageBox.Show(i.ToString());
    }
}

Windbg 根因分析

0:009> !dumpheap -type AxMSACAL.AxCalendar
Address       MT     Size
012c94f8 00978424   336  (2 instances)

0:009> !gcroot 012c94f8
ESP:12e5fc:Root: 012c8bd8(WindowsApplication4.Form1)-> 
                  012cbc78(System.Windows.Forms.LayoutEventArgs)-> 
                  012c94f8(AxMSACAL.AxCalendar)

GC Root 鏈:Form1 → LayoutEventArgs → axCalendar。LayoutEventArgs 佔有控制項參考,導致無法回收。

解決方向

  • 確保從 Controls 集合移除後,解除所有事件訂閱
  • 呼叫 Marshal.ReleaseComObject 釋放 COM 介面參考
  • 避免在事件處理器中捕獲控制項參考形成閉包
  • 考慮改用純 .NET 控制項替代 ActiveX

此問題揭示 Windows Forms 混用 COM 元件時的記憶體管理複雜性。

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