Dav*_*ten 6 .net memory-leaks gdi count handle
我的纯DotNET库在非托管桌面应用程序中作为插件运行.我一直在获得一个稳定的(虽然很低)崩溃报告流,似乎表明GDI句柄有问题(错误消息中的字体等恢复到系统字体,各种控件的显示中断,大规模崩溃后不久).
我的表单几乎没有控件,但我在用户控件中做了很多GDI +绘图.什么是告诉我正在使用多少手柄甚至泄漏的好方法?
谢谢,大卫
看一下GDIView(它是免费软件):
GDIView 是一个独特的工具,它显示每个进程打开的 GDI 句柄(画笔、笔、字体、位图等)列表。它显示每种类型的 GDI 句柄的总数,以及有关每个句柄的详细信息。该工具对于需要跟踪软件中 GDI 资源泄漏的开发人员非常有用。

(来源:nirsoft.net)  
请注意,自动刷新默认情况下处于禁用状态,但可以启用并配置特定时间间隔:Options -> Auto Refresh -> Every [N] seconds
[DllImport("User32")] 
extern public static int GetGuiResources(IntPtr hProcess, int uiFlags);
  public static void GetGuiResourcesGDICount()      
  { 
      //Return the count of GDI objects.          
      Console.WriteLine("GDICount"+GetGuiResources(System.Diagnostics.Process.GetCurrentProcess().Handle, 0));      
  }
  private void button1_Click(object sender, System.EventArgs e)
  {
      GetGuiResourcesGDICount();
  }
GDIView告知泄漏的是字体对象。然后,我将调用添加GetGuiResources到我们的日志记录代码中,以检测在何时触发了对象创建。
在我们的例子中,Label当控件的父项UserControl隐藏在后台窗口中时,我们将对其进行更新。这将导致GDI泄漏字体句柄。为了解决此问题,我们更改了逻辑以不更新Label除非当前在屏幕上可见。为了确定它是否可见,我们记录了UserControl上次绘制的时间。
我过去也曾遇到过同样的问题。为了检查您的应用程序分配了多少 GDI 对象,您可以使用名为GDIUsage的免费工具。
在我的例子中,应用程序崩溃是因为它分配了超过10.000 个 GDI 对象,这是 Windows XP 中的硬限制。也许值得研究一下。
我在这里写了关于这个问题的博客:
http://megakemp.com/2009/02/25/gdi-memory-leak-in-windows-forms/