GDI-句柄泄漏

Posted

技术标签:

【中文标题】GDI-句柄泄漏【英文标题】:GDI-Handle Leak 【发布时间】:2013-06-10 02:58:08 【问题描述】:

我遇到了 GDI-Handle 的问题。我了解 Windows 将每个应用程序的 GDI 句柄数量限制为 10.000。然后应用程序崩溃。

在我自己的系统和几个虚拟机上,GDI-Handles 的数量保持在 300 到 500 之间……不管我做什么。在客户项目中,它越来越高,直到几天后达到 10.000。

13.06.2013: 12:47 GDI-Handles 1550

13.06.2013: 12:59 GDI-Handles 1553

13.06.2013: 13:07 GDI-Handles 1557

13.06.2013: 13:55 GDI-Handles 1564

13.06.2013: 15:29 GDI-Handles 2193

13.06.2013: 16:47 GDI-Handles 2201

13.06.2013: 17:14 GDI-Handles 2201

13.06.2013: 17:21 GDI-Handles 2201

13.06.2013: 17:29 GDI-Handles 2263

为什么在另一台具有完全相同的 .NET 应用程序的 PC 上的行为如此不同?知道如何在系统上不安装 Visual Studio 的情况下调试它吗?

【问题讨论】:

如果有泄漏,我不会担心计算机细节,在修复之前总会有泄漏。您使用的版本有什么不同吗? 泄漏的可能不是您的代码。例如,OpenFileDialog 是一种将 shell 扩展注入到您的进程中的好方法,这种扩展可能会像那样行为不端。如果您根本无法重现此问题,那么您需要将其视为“病机”问题。 minidump 可以显示外部 DLL 被注入到您的程序中,但不是决定性的。 不,没有任何区别。我将构建复制到我的系统并对其进行了测试。但根本没有泄漏。也许我正在做与用户不同的事情,但我不这么认为......有没有办法记录与此应用程序关联的所有 GDI 句柄?它们是什么类型...来自哪个程序集...可能是它们在其中创建的方法...? 【参考方案1】:

我解决了这个问题。在系统上,我遇到了运行工具“GDIView”的错误。使用此工具,我能够确定导致问题的对象是位图。我发现 Bitmap 造成了麻烦,并发现我必须手动处理 IntPtr(那里的 GC 没有帮助)。

            ImageSource wpfBitmap = null;

            if (this.buttonImage != null)
            

                IntPtr hBitmap = this.buttonImage.GetHbitmap();

                wpfBitmap = Imaging.CreateBitmapSourceFromHBitmap(
                   hBitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());

                DeleteObject(hBitmap);
            

            return wpfBitmap;

所以我只是添加了“DeleteObject()”方法,泄漏就消失了。

【讨论】:

这不是一个真正的答案,除非你能解释为什么这不会在你自己的机器上造成问题。 它确实在我自己的机器上引起了问题。 Sayse 是绝对正确的。我只是没有在我的第一种方法中找到问题的触发因素 那你肯定需要更新你的问题,它与答案不匹配。

以上是关于GDI-句柄泄漏的主要内容,如果未能解决你的问题,请参考以下文章

检测 winforms 中的 gdi / 用户处理程序泄漏

为啥使用“RenderTargetBitmap”类会使 GDI 句柄数增加?

为啥控件的类名不好?不能创建新的 GDI 句柄?

GDI 设备环境句柄

在 Windows CE 6.0 中的进程之间共享 GDI 句柄

如何获取传递给 DrvEnablePDEV 的属于 GDI 引擎的“逻辑设备句柄”HDEV?