【问题标题】:What are Windows "USER objects"什么是 Windows“用户对象”
【发布时间】:2010-10-26 11:48:27
【问题描述】:

我正在尝试在我们的 MFC 代码中查找一个看起来像资源限制问题的问题。内存和CPU看起来不错。根据任务管理器上的进程选项卡,我们的 GDI 对象看起来与其他应用程序一致,但我们的 USER 对象似乎比其他应用程序大 10 倍。

什么是“USER 对象”,有什么限制?

【问题讨论】:

    标签: windows winapi mfc


    【解决方案1】:

    Mark Russinovich 是这方面的专家。他着有《Windows Internals》一书。幸运的是,不仅有书,还有article dating 2019-06-27

    首先他描述了 USER 对象:

    USER 对象之所以得名,是因为它们代表用户界面元素,如桌面、窗口、菜单、光标、图标和加速器表(菜单键盘快捷键)。

    然后继续描述极限:

    窗口管理器施加的一个基本限制是任何进程都不能创建超过 10,000 个 USER 对象。

    对 USER 对象数量的一个基本限制来自这样一个事实,即它们的标识符在 Windows 的第一个版本中是 16 位值,即 16 位。在更高版本中添加 32 位支持时,用户标识符必须保持限制为 16 位值,以便 16 位进程可以与窗口和其他由 32 位进程创建的 USER 对象进行交互。因此,65,535 (2^16) 是可以在会话中创建的 USER 对象总数的限制

    他还解释了号码mentioned by @Tobi

    由于历史原因,窗口必须有偶数标识符,因此每个会话最多可以有 32,768 个窗口

    【讨论】:

      【解决方案2】:

      阅读所有相关信息here

      对象类别

      系统提供三类对象:用户、图形设备接口(GDI)和内核。系统使用用户对象来支持窗口管理,使用 GDI 对象来支持图形,使用内核对象来支持内存管理、进程执行和进程间通信 (IPC)。有关创建和使用特定对象的信息,请参阅相关概述。

      here:

      用户对象

      用户界面对象仅支持每个对象一个句柄。进程不能继承或复制用户对象的句柄。一个会话中的进程不能引用另一个会话中的用户句柄。

      每个会话的理论限制为 65,536 个用户句柄。但是,每个会话可以打开的最大用户句柄数通常较低,因为它受可用内存的影响。用户句柄还有一个默认的每个进程限制。要更改此限制,请设置以下注册表值:

      HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\USERProcessHandleQuota
      

      此值可以设置为 200 到 18,000 之间的数字。

      【讨论】:

      • 当我将注册表设置更改为 17999 并重新启动我的进程时,它仍然崩溃。这是否需要重新启动或其他方式才能申请?
      • @FlorianStraub:可能需要重新启动,因为可以从用户模式访问这些对象,但内核仍会处理对它们的访问。所以内核需要刷新,只有重启才能完成。
      【解决方案3】:

      这是一篇“经典”的 MSDN 文章:Give Me a Handle, and I'll Show You an Object

      上次我跟踪 Windows 对象泄漏(我怀疑你有)Process Explorer 很方便(handley?)。下窗格可以显示一些已分配的系统对象,此外它还可以进行简单的 USER、GDI 等对象计数。

      desktop heap,它是一个内存池,句柄代表生命的真正“东西”(至少是一些句柄,至少不是内核句柄)。有时与其说分配了多少句柄,不如说是该句柄下的每个 object 使用了多少内存。您可以调试堆this way。要安装的是pain

      【讨论】:

        【解决方案4】:

        我不知道它们是什么,但我知道它们包括窗口句柄。

        对于窗口句柄,系统范围的最大值约为 32000,每个进程的最大值为 10000。(这可能只是 USER 对象限制,而不仅仅是窗口句柄。)

        如果您以某种方式泄漏窗口句柄,或者如果您使用大量窗口,则窗口句柄的数量可能非常多。 (请注意,即使是像文本标签这样的简单控件也会使用单个窗口句柄。)

        【讨论】:

        • 任何 Microsoft 引用的 32000 限制?
        • 我遇到了一个进程的 10000 限制。一旦达到限制,您将在尝试创建新的 winforms 对象时收到“错误创建窗口句柄”。
        • @ThomasWeller:Aardvark 发布的链接提到 64K 作为全局限制,但这是针对 Windows NT 的
        • @FlorianStraub:另请参阅我的回答 stackoverflow.com/a/62044509/480982,它解释了这两个数字
        猜你喜欢
        • 2018-11-02
        • 1970-01-01
        • 2019-01-26
        • 2014-06-30
        • 1970-01-01
        • 2017-08-15
        • 2011-06-12
        相关资源
        最近更新 更多