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());
}
}
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 介面參考此問題揭示 Windows Forms 混用 COM 元件時的記憶體管理複雜性。