【发布时间】:2015-08-10 08:29:57
【问题描述】:
我想我在我的桌面应用程序(.NET 4.0、WinForms、VB.NET)中发现了内存泄漏。不幸的是,我无法解释为什么会发生。
我有一个 Form 和一个自定义-TabControl(继承自 XtraTabControl - DevExpress)。这个TabControl 在每个TabPage 中显示一组不同的客户。如果您双击一行(客户),我会打开一个新的Form,其中包含客户的所有详细信息。在这个新的Form 中有一些DataGrids(同样是使用来自DevExpress 的GridControl 和GridView 的自定义控件)和许多其他控件(Labels、TextBoxes 等)。如果 detail-Form 已打开,则会使用新的客户数据进行更新。
以下是内存泄漏的一些事实:
- 启动应用程序后:已使用 77 Mb RAM; 2.640
EventHandlers持有 90 Kb RAM - 打开 25 个客户后:已使用 190 Mb; 75.016
EventHandlers持有 127 Mb RAM - 关闭两个表单后:仍然使用 190 Mb,66.216
EventHandlers持有 132 Mb RAM
我尝试System.GC.Collect(2, GCCollectionMode.Forced) 只是为了好玩(我知道我不应该这样做),但它根本没有改变任何东西。
我知道事件的发布者持有对订阅者的引用,因此如果发布者的寿命比订阅者的寿命长,那么它将使订阅者保持活动状态。但是如果我关闭所有两个Forms,不应该都很好吗?
编辑:这是打开 25 个客户并关闭 2 个表单后的内存屏幕截图。看起来,内存中还有很多控件:( (列翻译:对象类型 | 计数 | 大小 | 持有内存大小)
编辑 2:这是 ANTS Memory Profiler 的另一个屏幕截图。不幸的是,我无法从中得到线索:
希望大家能帮帮我,先谢谢了!
【问题讨论】:
-
这可能不是“内存泄漏”。让您的应用程序打开 10 分钟以查看 RAM 是否减少。想看看的想法 - 关闭后尝试
Disposing表单。此外,如果您调用AddHandler以编程方式添加事件处理程序,您应该在某处调用RemoveHandler。 -
我试试。以为我可以用
System.GC.Collect()模拟它,所以我不必等待。这两种形式得到处理。我还检查了是否所有子控件也都被释放了 - 效果很好(来自设计器的 Dispose-Code)。 -
获取 JetBrains dotMemory 等内存分析器,并在关闭表单后检查您的对象是否仍在内存中
-
我在打开 25 个客户并关闭 2 个表单后添加了一个屏幕截图。内存中还有很多控件。但为什么?关闭 2 个表单后,任何控件都不应有任何引用(或者我误解了什么)?
-
@roli09 我不熟悉这个分析器,它可以显示从根到泄漏对象的路径吗?看看它,你很可能会明白为什么它还在记忆中。
标签: .net vb.net winforms memory-leaks