首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >调试桌面堆耗尽

调试桌面堆耗尽
EN

Stack Overflow用户
提问于 2017-09-05 17:10:31
回答 1查看 2.2K关注 0票数 7

我目前正在支持一个产品,它似乎消耗了大量的桌面堆。这些二进制文件大多是.net,并且都将会话0作为非交互进程运行(它们都是已安装的windows服务的子进程)。因此,据我所知,它们不应该消耗任何桌面堆。

我们有几个环境间歇性地在系统日志中报告事件ID 243,然后在应用程序日志中报告事件ID 1000;应用程序日志中的异常始终为0xc0000142。最终,我们的一个服务也会因为一些隐秘的(无用的)消息而失效。不幸的是,我们一直没能捕捉到这个异常,但这些似乎都是桌面堆耗尽的清晰指标。

我正在试图找出是什么消耗了这么多的桌面堆,以便我可以追踪原因。但这就是我被困住的地方。最初我计划安装Desktop Heap Monitor,但在几次尝试使其工作失败后,我意识到它在任何XP以上的系统上都不受支持。我在某处读到Process Explorer应该能够为我提供相同的信息,因此我们一直在监视PE中的以下对象:

  1. 句柄计数
  2. GDI对象
  3. 用户对象

报告事件243时的句柄计数值与几天前没有发生问题时没有显著不同,甚至在进程启动后的几分钟内也没有显著差异。GDI和USER对象都是零。所以,我不知道到底是什么在耗尽桌面堆,也不知道如何进一步调试它。我在某处读到WeakEventManager可能会导致这个问题,但我们似乎并没有使用这个。

我已经在google和SO上彻底搜索了这个东西,到目前为止我还没有找到任何东西。我真正想要的是确定哪个进程正在耗尽堆,或者至少哪个进程消耗最多。如果有人对如何做到这一点有任何建议,我将不胜感激。

EN

回答 1

Stack Overflow用户

发布于 2018-04-06 18:19:26

一个旧的线程,但我想我应该循环回来,以防将来有人遇到这个问题。经过一些调试之后,我们确定了是哪个进程导致了问题。我决定将WinDbg附加到流程中,并在CreateWindowEx和NtDestroyWindow上设置bp。果然,CreateWindowEx确实被调用来创建一个隐藏的窗口;从堆栈上的参数中,我能够获得该窗口的类(它总是相同的),这有助于进一步缩小范围。

随着时间的推移,我开始注意到对NtDestroyWindow的调用数量少于对CreateWindowEx的调用数量。所以我沿着callstack往下看是什么在创建窗口...有一个类构造函数和析构函数(本机的,非托管的)。我们似乎没有像调用构造函数那样频繁地调用析构函数,所以随着时间的推移,我们泄漏了这些类的一些实例,并且随着时间的推移,我们还“泄漏”了一个隐藏窗口,该窗口随着时间的推移而积累,并导致桌面堆耗尽问题。从这里,我们设法追踪到该类的实例没有被销毁的地方,并能够解决这个问题。

然而,我对自己的命运并不满意,我很好奇为什么Process Explorer对我来说并不像我期望的那样有用。在这段时间里,它一直显示零个用户对象,即使我知道该进程正在创建窗口对象。然后我意识到PE只能显示在同一会话中运行的进程的数据。因此,为了跟踪服务的windowo对象,我不得不在会话0中运行它。在PsExec和下面的帖子的帮助下,我能够在会话0中运行PE并切换到它。

https://superuser.com/questions/426868/interactive-session-0-in-windows-7

https://blogs.technet.microsoft.com/home_is_where_i_lay_my_head/2012/10/09/windows-8-interactive-services-detection-error-1-incorrect-function/

从那里,我确实可以看到进程有超过1,000个用户对象。我还能够运行WinSpy并确认我的发现。当然,在这个阶段,这一切都是理论上的,但也许这将在未来对某些人有用。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46051165

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档