【问题标题】:How to debug "Not enough storage is available to process this command"如何调试“没有足够的存储空间来处理此命令”
【发布时间】:2017-01-18 03:11:04
【问题描述】:

我们已经开始体验Not enough storage available to process this command。该应用程序是WPF,正常工作几个小时后开始弹出异常。

System.ComponentModel.Win32Exception (0x80004005): Not enough storage is available to process this command
   at MS.Win32.UnsafeNativeMethods.RegisterClassEx(WNDCLASSEX_D wc_d)
   at MS.Win32.HwndWrapper..ctor(Int32 classStyle, Int32 style, Int32 exStyle, Int32 x, Int32 y, Int32 width, Int32 height, String name, IntPtr parent, HwndWrapperHook[] hooks)
   at System.Windows.Interop.HwndSource.Initialize(HwndSourceParameters parameters)
   at System.Windows.Window.CreateSourceWindow(Boolean duringShow)
   at System.Windows.Window.CreateSourceWindowDuringShow()
   at System.Windows.Window.SafeCreateWindowDuringShow()
   at System.Windows.Window.ShowHelper(Object booleanBox)
   at System.Windows.Window.Show()
   at System.Windows.Window.ShowDialog()

我的理解是这是某种内存不足异常,特定于windows resources 的分配。这可能是什么原因,我该如何调试?


更新

我已经查看了@Thili77 (this one) 建议的主题。我使用 GDIView 和任务管理器来查看我们的应用程序执行期间消耗的句柄(taskmgr 中的句柄、用户对象和 GDI 对象),它们看起来并没有增长。我的下一个测试是尝试在没有 VS 的情况下运行一天(之前它在 VS 主机进程下运行)并检查是否仍然发生这种情况。如果有人有任何建议或提示,我仍在寻找任何建议或提示

更新 #2 它发生在没有托管 VS 的新的干净 PC 上。句柄、用户对象和 GDI 对象在崩溃期间正常。当 PC 处于崩溃状态时,无法正常工作 - 看起来句柄确实泄漏了,但 ProcMon 没有显示这些值的大数字。 奇怪的是,这总是发生在晚上 7 点到 8 点左右,那时办公室里没有人,我什么时候开始运行应用程序也没关系。这已经是第三次这样的崩溃了。巧合?我唯一注意到我觉得奇怪的是应用程序的大量页面错误,并且不断增长。这可能是相关的吗?不再出现,请参阅更新 #3

更新 #3

接下来是我遇到的崩溃的详细信息。系统是x86,app是x86,W7 SP1。 屏幕截图中显示的当前状态正好在崩溃之后,windbg 暂停了进程。 由于某种原因,现在异常有不同的消息:The operation completed successfully。但它仍然是来自同一段代码的相同 Win32Exception。

我还需要确定我正在运行的桌面堆数量减少并且 AppAnalyzer Basic 选项处于打开状态 - 以使故障更加频繁(这似乎有效)。时间假设确实是一个巧合,不再注意到与时间相关的共享主题。

【问题讨论】:

  • 在投反对票之前有人愿意表达自己吗?
  • This 会帮助你。
  • @Thili77 谢谢。不知怎的,我忽略了这个话题
  • 既然你提到了一天中的特定时间,这是一个特殊的公司网络,将组策略推送到所有 PC? “新的干净 PC”是同一网络的一部分,还是发生在独立的 PC 上?
  • 根据描述,内核内存池耗尽是最合乎逻辑的原因。不是您的程序必然引起的那种问题。谷歌“windows 诊断内核内存池耗尽”的相关命中。

标签: c# wpf


【解决方案1】:

一种可能是global atom table 已用完可用空间。表中有 0x4000 个字符串原子的限制,分配给表的空间总量也有限制。窗口类是该表中的内容之一。

我自己从未尝试过调试此类问题,但我确实找到了一篇关于使用 WinDbg 检查此问题的文章:Identifying Global Atom Table Leaks。您可能希望将其作为可能的原因进行调查。

如果这是罪魁祸首,一个可能的原因是应用程序没有关闭 Window 实例。 HwndWrapper 在其 Dispose 中清理其全局原子,这是响应 WM_DESTROY 发生的,这是响应在 Window 上调用 Close(或设置 DialogResult,如果值更改并且最终关闭窗口)通过调用 ShowDialog 而不是 Show 来显示窗口)。原子泄漏可能还有其他可能的原因。

附:我怀疑这是因为“没有足够的存储空间来处理这个命令”是RegisterClassEx无法添加到全局原子表时返回的错误。

【讨论】:

  • 很遗憾我有另一个项目的截止日期,所以我不得不推迟我的调查,所以我现在无法检查。但这绝对是迄今为止我得到的最佳答案,非常赏金
【解决方案2】:

看起来像是微软没有故意解决的问题,请查看this Connect link,其中声明:

感谢您的反馈。但是,这个问题将不会在 WPF 的下一版本中得到解决。谢谢你。 –WPF 团队。

提供了一种解决方法,它可能会有所帮助:

您可以通过将以下代码添加到您的线程 proc 来解决此错误:

Dispatcher dispatcher = Dispatcher.CurrentDispatcher;
dispatcher.BeginInvokeShutdown(DispatcherPriority.Normal);
Dispatcher.Run();

这要求与线程关联的调度程序立即关闭。

【讨论】:

  • 感谢您的建议。看起来这与问题无关 - 我检查了消耗的句柄的数量并且它们没有增长。我们还有一个带有单个 STA 线程的普通 WPF 应用程序。
  • 这不可能是原因。他会在任务管理器中看到这一点,用户对象计数器会很高。而且它不会破坏整个操作系统的稳定性。
  • @Alex 你能检查一下这个类似的问题吗 - stackoverflow.com/questions/47006484/…
【解决方案3】:

根据我的经验,如果您的 UI 线程挂起并且其他线程继续将消息发送到主应用程序 UI 调度程序,我会收到这种类型的异常。因此,在某个类型的时间段内,消息队列已满,您将收到此异常。

要进行调试,您可能需要在调试会话期间在 VS 中找到您的线程 1(即 UI)并监控它的活动。也许在某些外部事件等上有一些无限的服务员。

【讨论】:

    猜你喜欢
    • 2014-06-23
    • 2015-01-22
    • 2012-05-14
    • 1970-01-01
    • 2017-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-03
    相关资源
    最近更新 更多