如何调试“没有足够的存储空间来处理此命令”

时间:2017-01-09 08:37:51

标签: c# wpf

我们已经开始体验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中的句柄,USER对象和GDI对象),看起来它们看起来并不像它们正在增长。我的下一个测试是尝试在没有VS的情况下运行它一天(之前它在VS主机进程下运行)并检查是否仍然发生这种情况。如果有人有任何建议或提示,我仍在寻找任何建议或提示

更新#2 它发生在没有托管VS的新干净PC上。在崩溃期间,句柄,USER对象和GDI对象都可以。当PC处于崩溃状态时,没有任何工作正常 - 看起来手柄真的泄露了,但ProcMon没有显示这些值的大数字。 还奇怪的是,这总是发生在下午7点到8点左右,当时办公室里没有人,当我启动应用程序运行时没关系。这已经是第三次崩溃了。巧合?只有我注意到我觉得奇怪的是应用程序的大量页面错误,它不断增长。这可能是相关的吗?不再出现,请参阅更新#3

更新#3

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

我还需要确定我运行的桌面堆数量减少,AppAnalyzer Basic选项开启 - 以便使故障更频繁(这似乎有效)。时间假设确实是巧合,没有时间相关的共享主题再次注意到。 System Information Processes MyApp process info

3 个答案:

答案 0 :(得分:4)

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

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

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

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

答案 1 :(得分:1)

看起来像是Microsoft未故意解决的问题,请查看this Connect link,其中说明了:

  

我们感谢您的反馈。但是,下一版本的WPF将不会解决此问题。谢谢。   -WPF团队。

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

  

您可以通过在线程proc中添加以下代码来解决此问题:

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

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

答案 2 :(得分:0)

根据我的经验,我收到了这种类型的异常,以防你的UI线程挂断,其他线程继续将消息放到主应用程序UI调度程序中。因此,在某段时间内,消息队列已满,而且您将收到此异常。

要调试您可能需要在调试会话期间在VS中找到您的线程1(这是UI)并监视它的活动。也许在某些外部事件或其他事件上有一些无限的服务员。