Windows 7 中一个进程的 GDI 对象上限是多少?

Posted

技术标签:

【中文标题】Windows 7 中一个进程的 GDI 对象上限是多少?【英文标题】:What's the upper limit on GDI objects for one process in Windows 7? 【发布时间】:2012-04-01 04:21:45 【问题描述】:

有一个 GDI 泄漏的应用程序最终会达到 10,000 个已分配的 GDI 对象并崩溃。我尝试将GDIProcessHandleQuota 增加到 20,000,但是当它达到 10,000 个对象时程序仍然崩溃。我们目前正在修复这个漏洞,但出于好奇——有没有办法增加单个进程的 GDI 限制?还是 10k 是单个应用程序的硬限制?

【问题讨论】:

GDIProcessHandleQuota 增加到20,000 对我有用。注册表更改后必须重新启动系统。在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\GDIProcessHandleQuota 处更新了注册表项 【参考方案1】:

10K 是硬限制。

GDI 对象代表图形设备界面资源,如字体、位图、画笔、钢笔和设备上下文(绘图表面)。就像对 USER 对象所做的那样,窗口管理器将进程限制为最多 10,000 个 GDI 对象 [...]

Mark Russinovich 有一系列文章深入探讨了 Windows 中的各种限制。您可能会发现这两个很有用:

Pushing the Limits of Windows: USER and GDI Objects – Part 1 Pushing the Limits of Windows: USER and GDI Objects – Part 2

Raymond Chen 的另一篇好文章:

Why is the limit of window handles per process 10,000?

【讨论】:

感谢您的信息。在这里发布之前,我浏览了推动 Windows 限制的文章,并注意到 Mark R. 没有向您展示如何修改注册表以将默认 GDI 限制扩展到 10k 以上,所以我认为这可能是他忽略的东西。如果它对我的机器没有明显影响,我仍然很困惑为什么这个数字可以高达 65535。我可以为我的所有进程消耗超过 10k 的对象,而在 Windows 中没有延迟,直到一个应用程序达到 10k 时我才会崩溃。 10K is a hard limit. 这似乎不是真的。您能否在JimR's answer中添加有关您所指的限制关系的详细信息 有一个名为 GDIProcessHandleQuota 的注册表项。改变这个限制似乎并不难。我认为你混合了 GDI 句柄和用户句柄。 我知道这个帖子已经过时了,但是对于那些想要查看上面的 Russinovich 链接(至少对我来说已经死了)的人来说,这里是活的:techcommunity.microsoft.com/t5/windows-blog-archive/… 和 techcommunity.microsoft.com/t5/windows-blog-archive/… 【参考方案2】:

有一个可行的解决方案。我在这里处理一个行为不端的供应商应用程序,它分配了大量的 GDI 对象,这个解决方案允许它在大多数时间工作......

reg query "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems" /v windows

查找SharedSection=,它应该是由逗号分隔的 3 个数字。一次将中间数增加 1024,看看是否能解决您的问题。您正在使用此变量控制“桌面堆”的数量,这在过去允许我运行行为不端的 GDI。

查看KB184802 了解更多信息。搜索 SharedSection 以找到页面的相关部分。

【讨论】:

宾果游戏!我增加了桌面堆,现在可以处理超过 10,000 个 GDI 对象。我们的首席开发人员已经提出了一个补丁,但现在我的好奇心得到了解决。谢谢 嗨!我的 SharedSection 设置为 1024,20480,768 但我的 python.exe 仍然崩溃。我读过将桌面堆增加到 20480 以上是不安全的吗?你有什么看法? @Aleksandar:如果我没记错的话,所有这些数字的总和不能超过 48MB。这些数字以千字节为单位留出内存。根据您运行的服务数量和服务,还有一些其他限制。阅读 Derek Parks 答案中的前 3 个链接以获得良好的背景。还要确保您创建的 GDI 对象不超过 10,000 个。【参考方案3】:

我可以通过仅更改 GDIProcessHandleQuota 将我的 GDI 对象从 10000 增加到 15000,但这需要重新启动才能生效。我不必更改我的 SharedSection 值,只需要重新启动。

虽然 10000 似乎是一个很大的数字,但我的应用程序有一个很大的 UI,其中包含许多按钮、画笔、图像、图标等。一旦应用程序启动,对象的数量只会在用户执行值得的操作时增加增加。没有 GDI 对象从应用程序中泄漏。为了测试我的解决方案,我确实添加了一个“泄漏”方法,这样我就可以在任务管理器中观察当 GDI 对象的数量增加到超出各种限制时会发生什么。

【讨论】:

以上是关于Windows 7 中一个进程的 GDI 对象上限是多少?的主要内容,如果未能解决你的问题,请参考以下文章

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

API获取当前进程的用户对象和GDI对象

进程关闭过程

如何在 Windows 窗体中创建 GDI 泄漏!

深入理解Windows系统——2.Windows对象管理器

gdi 对象保存在哪里?