检测c#应用程序中的窗口句泄漏

时间:2009-12-14 13:59:35

标签: c# detect memory-leaks

昨天我遇到了这个例外:

Win32Exception: Fehler beim Erstellen des Fensterhandles

可能会翻译:

Win32Exception: Error while creating the windowhandle

我知道如何解决这个问题(甚至在主题上写了一篇简短的blog post - 用德语写的)

但是我不知道我的应用程序可能在哪里'泄漏'没有处置控件,仍然有窗口句柄。

有没有办法检测/查找实例

  • 实施IDisposable
  • Parent == null

符合此约束的对象似乎是不错的选择。

3 个答案:

答案 0 :(得分:2)

任何体面的内存分析器都会显示控件实例。它们不会被垃圾收集,它们的Handle属性使它们保持活力。将有近10,000个。您还可以使用任务管理器查看它,使用视图+选择列并勾选用户对象。在测试应用程序时观察计数增加应提供一个不错的提示。

代码审查也应该走很长的路,没有太多可能的方法来泄漏窗口。首先查看最常见的情况,即调用Controls.Clear()或Controls.Remove / At()的代码,但不会处理控件。下一个常见的情况是SystemEvents类,您必须显式取消订阅其事件。其余的不容易找到,你需要那个探查器。

使用Reflection在技术上可以在运行时自己查找句柄。句柄存储在System.Internal.HandleCollector.handleTypes []中。嗯,技术上。

答案 1 :(得分:0)

实现IDisposable的每个对象都有Dispose方法。当不再需要该对象时,应该调用此方法。它是仅在单个方法中使用,用using语句包围它(自动调用Dispose)。如果它是您班级的成员变量,那么您的班级应该实现IDisposableFxCop对此有一个检查规则。

答案 2 :(得分:0)

如果没有收集它们是因为某些其他对象正在引用您的控件,则调用dispose和将parent设置为null都不够。也许你是附加于事件而不是从它们中删除。

特别检查从附件未包含的控件附加事件的情况,在这种情况下,处理控件时应始终与事件分离,否则控件仍将继续被附件引用,从而它不会被发布