我有一個隨着時間的推移泄漏UserControls的CF應用程序。它花了一些時間,但我縮小了範圍,甚至在整個框架中複製了行爲(3.5)。既然這兩種行爲都存在,我不想把它稱爲一個錯誤,但我肯定不明白爲什麼會發生這種情況,並希望有人能夠對此有所瞭解。GC沒有最終化UserControl?
因此,我創建一個簡單的WinForms應用程序與一個窗體和按鈕。點擊按鈕會交替創建一個新的UserControl和處理該控件。很簡單。
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
UserControl1 m_ctl;
private void button1_Click(object sender, EventArgs e)
{
if (m_ctl == null)
{
m_ctl = new UserControl1();
m_ctl.Visible = true;
this.Controls.Add(m_ctl);
}
else
{
this.Controls.Remove(m_ctl);
m_ctl.Dispose();
m_ctl = null;
GC.Collect();
}
}
}
這裏是UserControl。它只是跟蹤實時(即未完成)實例的數量。它沒有任何內容,只有一個標籤,所以我可以直觀地確認它在表單上。
public partial class UserControl1 : UserControl
{
private static int m_instanceCount = 0;
public UserControl1()
{
var c = Interlocked.Increment(ref m_instanceCount);
Debug.WriteLine("Instances: " + c.ToString());
InitializeComponent();
}
~UserControl1()
{
var c = Interlocked.Decrement(ref m_instanceCount);
Debug.WriteLine("Instances: " + c.ToString());
}
}
這裏很奇怪的是實例數無限增長。最終,在設備上,我耗盡內存。我懷疑我也會在個人電腦上,我只是不想點擊下一年的按鈕。
現在,如果我改變用戶控件的默認,設計器生成這樣的Dispose方法,簡單地將ReRegisterForFinalize方法調用:
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
if (disposing)
{
GC.ReRegisterForFinalize(this);
}
}
然後,它的行爲完全符合市場預期,採集過程中敲定實例(當手動或自動) 。
那麼爲什麼會發生這種情況呢?很明顯,該基地正在呼籲SuppressFinalize,但具體爲什麼會發生這種情況,爲什麼以奧丁的名義是默認行爲?
+1實際上有一個真正的理由考慮使用GC, – Sayse
考慮到裏德(抱歉不能成爲實際的解決方案幫助!)回答,真實代碼中的終結器是做什麼的?無法調用終結器導致泄漏? – svick
真正的代碼根本沒有終結器。他們確實已經實施了Dispose,並且正在處理位圖等。 – ctacke