void Foo()
{
System.Windows.Forms.Form f = new System.Windows.Forms.Form();
f.Show();
}
据我了解, f 包含对表格的引用。但是 f 是一个局部变量,当控件离开花括号时它将超出范围。但表格仍处于打开状态。我尝试调用 GC.Collect(),但表单仍然打开。
还有一种情况。
private void button2_Click(object sender, EventArgs e)
{
Timer t = new Timer();
t.Enabled = true;
t.Interval = 1000;
t.Tick += new EventHandler(t_Tick);
}
void t_Tick(object sender, EventArgs e)
{
}
在这种情况下, t 永远不会被垃圾收集。经过大量研究,我发现当我设置 t.Enabled = true 时,Timer 类使用 - GCHandle.Alloc 请求 GC 不收集。伙计们,这是内存泄漏的一大来源。除非我设置 t.Enabled = false,否则即使我们关闭表单,整个表单也会被泄露。
在第一个示例代码中,我无法理解为什么即使在我触发 GC.Collect() 之后表单也没有被垃圾收集。在反射器中,我看到 ControlNativeWindow 已在内部使用 GCHandle.Alloc 的 Form 中使用。是这个原因吗。。作为 .NET 库的用户,我始终相信,当一个引用无法访问时,它就会有机会进行垃圾收集。当然,垃圾收集和从内存中的实际释放是不确定的。但我的问题是——我对这两个例子的理解是否正确?如果有对象即使在无法访问后仍然可以生存,那么我将如何跟踪它以防止内存泄漏?