ser*_*hio 6 .net memory-leaks event-handling .net-2.0
我分析了一个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)
从内存分配的角度来看?
提供大量事件的类使用它EventHandlerList来更有效地处理内存,方法是仅在需要时而不是在声明事件时为事件支持字段分配空间。因此,主窗体的所有事件都存储在那里。
我希望子窗体正在监视其父窗体何时可以关闭(这是常见的用例),并且当它收到该事件时,它不会取消订阅FormClosing该FormClosed事件。然而,这只是一个猜测。要进行确认,请查看您的子表单实现并查找它订阅父表单事件的所有情况,然后确保这些事件有相应的取消订阅。
更新
您发现未删除的菜单处理程序很可能是您看到的问题的根源。尝试添加删除调用,看看是否可以解决泄漏问题。