请考虑以下代码:
class TestTimerGC : Form
{
public TestTimerGC()
{
Button btnGC = new Button();
btnGC.Text = "GC";
btnGC.Click += (sender, e) => GC.Collect();
this.Controls.Add(btnGC);
System.Windows.Forms.Timer tmr = new System.Windows.Forms.Timer();
tmr.Interval = 1000;
tmr.Tick += (sender, e) => this.Text = DateTime.Now.ToString();
tmr.Start();
}
}
Run Code Online (Sandbox Code Playgroud)
如果我没有弄错,在tmr变量超出范围之后,Timer就不会在任何地方引用它,因此它应该有资格进行垃圾收集.但是当我点击GC按钮时,计时器继续运行,所以我猜它没有被收集......
有没有人对此有解释?
PS:当然,这不是一个真正的程序,我只是想向别人证明一点...但我的证据不起作用;)
我分析了一个VB.NET项目,并且有一些对象(子MDI表单)被处理,但没有被GC删除.
MemoryProfiler分析发现以下内容:
"这个实例被释放并且仍然间接地由一个EventHandler生成.这通常表明EventHandler没有被正确删除,并且是内存泄漏的常见原因.下面的实例直接由EventHandler生成.调查它们以获得更多有关此问题的信息......"
现在,我试着弄清楚这应该是什么意思以及如何解决它.
我有一个MDI表格和一个子表格.GC打开/关闭后不会收集子表单,显然是因为MDIForm仍然(间接?)引用了EventHandlerList...
它可以是什么,我该如何解决它?
我尝试了在这个线程中推荐的修复,因为在MDI引用中有问题PropertyStore,现在这个被淘汰了,但是出现EventHandlerList了对子窗体的MDI 引用...
经过一些代码分析,我观察了一些
AddHandler newMenu.Click, AddressOf ClickMenu
Run Code Online (Sandbox Code Playgroud)
没有事先RemoveHandler newMenu.Click, AddressOf ClickMenu.这可能是主要原因吗?
并且,提议,是 Handles
Private Sub ClickMenu(sender as Object, e as EventArgs) Handles newMenu.Click
Run Code Online (Sandbox Code Playgroud)
更好的
RemoveHandler newMenu.Click, AddressOf ClickMenu
AddHandler newMenu.Click, AddressOf ClickMenu
Run Code Online (Sandbox Code Playgroud)
从内存分配的角度来看?