有一个 GDI 泄漏的应用程序,最终将达到 10,000 个分配的 GDI 对象并崩溃。我尝试将GDIProcessHandleQuota增加到 20,000,但是当达到 10,000 个对象时程序仍然崩溃。我们目前正在修复这个漏洞,但出于好奇——有没有办法增加单个进程的 GDI 限制?还是 10k 是单个应用程序的硬限制?
3 回答
10K 是硬限制。
GDI 对象代表图形设备接口资源,如字体、位图、画笔、钢笔和设备上下文(绘图表面)。正如对 USER 对象所做的那样,窗口管理器将进程限制为最多 10,000 个 GDI 对象[...]
Mark Russinovich 有一系列文章深入探讨了 Windows 中的各种限制。您可能会发现这两个很有用:
Raymond Chen 的另一篇好文章:
有一个可能有效的解决方案。我在这里处理一个行为不端的供应商应用程序,它分配了大量的 GDI 对象,这个解决方案允许它在大多数时间工作......
做
reg query "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems" /v windows
查找SharedSection=
应该是用逗号分隔的 3 个数字。一次将中间数增加 1024,看看是否能解决您的问题。您正在使用此变量控制“桌面堆”的数量,该变量过去允许我运行行为不端的 GDI。
查看KB184802了解更多信息。搜索 SharedSection 以查找页面的相关部分。
我可以通过仅更改 GDIProcessHandleQuota 将我的 GDI 对象从 10000 增加到 15000,但这需要重新启动才能生效。我不必更改我的 SharedSection 值,只需要重新启动。
虽然 10000 似乎是一个很大的数字,但我的应用程序有一个很大的 UI,其中包含许多按钮、画笔、图像、图标等。一旦应用程序启动,对象的数量只有在用户做了一些值得增加的事情时才会增加。没有 GDI 对象从应用程序中泄漏。为了测试我的解决方案,我确实添加了一个“泄漏”方法,这样我就可以在任务管理器中观察当 GDI 对象的数量增加到超出各种限制时会发生什么。