事件处理程序和内存泄漏 [英] Event handler and memory leaks

查看:227
本文介绍了事件处理程序和内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我分析一个VB.NET项目,并且有一些对象(儿童 MDI 表单)已被 GC 处理但未被删除。

I analyze a VB.NET project and there are some objects (child MDI form) that are disposed, but not removed by the GC.

MemoryProfiler分析发现以下内容:

The MemoryProfiler analysis find, among others, the following:


此实例处理并仍然
由EventHandler间接生成
这通常表示
EventHandler没有被正确的
删除,是
内存泄漏的常见原因,下面的例子是
直接根据EventHandler $ s
调查他们获得更多关于这个问题的
信息...

"This instance is disposed and still indirectly rooted by an EventHandler. This often indicates that the EventHandler has not been properly removed and is a common cause of memory leaks. The instances below are directly rooted by EventHandler(s). Investigate them to get more information about this issue..."

现在,我试图弄清楚这应该是什么意思,以及如何解决它。

Now, I try to figure out what should this mean and how to fix it.

我有一个MDI窗体和一个子窗体。子窗体在开/关之后不会由GC收集,显然是因为MDIForm EventHandlerList ...引用的仍然(间接?)...

I have a MDI form and a child form. The child form is not collected by the GC after a open/close, apparently because remains still (indirectly?) referenced by the MDIForm EventHandlerList...

可以做什么,如何解决?

What can it be and how do I to fix it?

我尝试在此线程,因为在 PropertyStore中的MDI引用有问题,现在这个消除了,但是出现了MDI EventHandlerList 引用子表单...

I tried the fix recommended in this thread, because had a problem with the MDI reference in the PropertyStore, now this eliminated, but appeared the MDI EventHandlerList reference to the child form...

经过一些代码分析,我观察到一些

After some code analysis I observed some

AddHandler newMenu.Click, AddressOf ClickMenu

没有前面的 RemoveHandler newMenu.Click,AddressOf ClickMenu 。可能是主要原因吗?

without preceding with RemoveHandler newMenu.Click, AddressOf ClickMenu. Could it be the main cause?

而且,一个提议是句柄

Private Sub ClickMenu(sender as Object, e as EventArgs) Handles newMenu.Click

更好的

RemoveHandler newMenu.Click, AddressOf ClickMenu
AddHandler newMenu.Click, AddressOf ClickMenu

从内存分配的角度来看?

from the memory allocation point of view?

推荐答案

EventHandlerList 被提供大量事件的类使用,以便更有效地处理内存在需要时为事件支持字段分配空间,而不是在声明事件时分配空间。因此,主表单的所有事件都存储在那里。

The EventHandlerList is used by classes that provide large numbers of events to more efficiently handle memory by only allocating space for the event backing field when it is needed rather than when the event is declared. All events for the main form are therefore stored there.

我希望子表单在父级可能关闭时监控(这是一个常见的用例),而且在收到该事件时,没有取消订阅 FormClosing FormClosed 事件。但是,这只是一个猜测。要确认,请查看您的子表单实现,并查找从父表单订阅事件的所有情况,然后确保相应的取消订阅这些事件。

I would expect the child form was monitoring when its parent may close (this is a common use-case) and it didn't unsubscribe from the FormClosing or FormClosed event when it received that event. However, that's just a guess. To confirm, look at your child form implementation and find all cases where it subscribes to events from the parent form, then make sure there is a corresponding unsubscription from those events.

更新

您发现没有删除的菜单处理程序可能是您看到的问题的根源。尝试添加删除呼叫,看看是否解决了泄漏。

Update
The menu handler you found that was not removed could well be the root of the issue you see. Try adding the remove call and see if that addresses the leak.

这篇关于事件处理程序和内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆