Win32Exception没有足够的存储空间来处理此命令

通过我为MaxTo自动崩溃收集,我收到了以下崩溃报告:

V8.12.0.0 - System.ComponentModel.Win32Exception - :Void UpdateLayered():0 Version: MaxTo8.12.0.0 Exception: System.ComponentModel.Win32Exception Error message: Not enough storage is available to process this command Stack trace: at System.Windows.Forms.Form.UpdateLayered() at System.Windows.Forms.Form.OnHandleCreated(EventArgs e) at System.Windows.Forms.Control.WmCreate(Message& m) at System.Windows.Forms.Control.WndProc(Message& m) at System.Windows.Forms.ScrollableControl.WndProc(Message& m) at System.Windows.Forms.ContainerControl.WndProc(Message& m) at System.Windows.Forms.Form.WmCreate(Message& m) at System.Windows.Forms.Form.WndProc(Message& m) at MaxTo.MainForm.WndProc(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) 

另一个堆栈跟踪:

 Version: MaxTo2009.9.0.0 Exception: System.ComponentModel.Win32Exception Error message: Not enough storage is available to process this command Stack trace: at System.Windows.Forms.Form.UpdateLayered() at System.Windows.Forms.Form.OnHandleCreated(EventArgs e) at System.Windows.Forms.Control.WmCreate(Message& m) at System.Windows.Forms.Control.WndProc(Message& m) at System.Windows.Forms.ScrollableControl.WndProc(Message& m) at System.Windows.Forms.ContainerControl.WndProc(Message& m) at System.Windows.Forms.Form.WmCreate(Message& m) at System.Windows.Forms.Form.WndProc(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) 

在这个最新的堆栈跟踪中,根本没有对MaxTo的引用,并且我得到的90%的崩溃都具有类似于上面的堆栈跟踪。

在网上阅读我发现如果你忘记释放或处理变量,这个错误是很常见的。 在查看我的WndProc ,似乎有时会遇到问题,我找不到一个挂在任何对象引用上的地方。 除了一个变量之外的所有变量都是WndProc的本地变量,因此在方法终止时应该进行垃圾收集。

 protected override void WndProc(ref Message m) { base.WndProc(ref m); // I'm assuming the first trace can be caught here IntPtr hwnd = m.WParam; // Our hook tells us something got maximized if (Win32Import.UWM_MAXIMIZE == (UInt32)m.Msg) { // Figure out if we are temporarily disabled or using alternative profiles KeyStateInfo keyState = KeyboardInfo.GetKeyState(Settings.AlternativeProfileKey); Rectangle r = FindRectangle(MousePosition, (Settings.EnableAlternativeProfile && keyState.IsPressed ? AlternativeRegions : Regions)); // Did we find a rectangle to place it in? if (r != Rectangle.Empty) { Rectangle position = Win32Import.GetWindowRectangle(hwnd); Rectangle previousPos = GetLocation(hwnd); if (position == r && previousPos != Rectangle.Empty) { // We are restoring the original position Win32Import.SetWindowPos(hwnd, IntPtr.Zero, previousPos.X, previousPos.Y, previousPos.Width, previousPos.Height, Win32Import.SWP_NOZORDER | Win32Import.SWP_NOSENDCHANGING); } else { // We are maximizing to a region Win32Import.ShowWindow(hwnd, Win32Import.WindowShowStyle.Restore); Win32Import.SetWindowPos(hwnd, IntPtr.Zero, rX, rY, r.Width, r.Height, Win32Import.SWP_NOZORDER | Win32Import.SWP_NOSENDCHANGING); // Make sure we remember this location RememberLocation(hwnd, position); } } } else if (MaxTo64WindowHandleMessage == m.Msg) { // Store the window handle of our 64-bit subprocess SubProcess64WindowHandle = m.WParam; } } 

即使在多天运行程序时,我也无法重现错误。

我的假设是系统在未碎片化的内存或GDI句柄上都很低,但我无法在任何地方确认这一点。 关于此错误似乎没有任何好的文档。

有什么想法可能是什么? 我可以做任何事情来防止这个错误吗?

更新 :由于缺乏合适的解决方案,问题被重新打开了更多的堆栈跟踪。 简单地忽略它并不能解决问题。

泄漏或使用许多GDI对象/句柄。 这些可能导致资源堆短缺。 您可能无法重现,因为您的用户可能正在运行其他GDI资源繁重程序或使用终端服务器,在这种情况下,他们必须与其他用户共享一些堆。 请参阅系统错误。 代码:8。没有足够的存储空间来处理此命令

在这里,您可以阅读有关Desktop Heap Monitor工具的信息,以诊断桌面堆问题。

这里和这里和这里是GDI泄漏检测工具。

您的程序可能正在泄漏内核资源。 使用Taskmgr.exe开始诊断此问题。 查看+选择列,检查用户对象,GDI对象和句柄计数。 运行您的程序,观察其中任何一个是否稳步增加。 一旦其中一个达到10,000,你的程序就会死亡。

通过快速查看泄漏的方法,您可以开始注释代码以查看泄漏发生的位置。 它可能与你的“钩子”有关。

问题可能不在你的WndProc中 – 你在调用堆栈中看到它的原因是因为Windows上与GUI相关的几乎所有内容都通过WIN32窗口过程。 在您的控件中覆盖它只是为您提供了一个钩点,以便在更高级别的.NET框架处理完成之前处理低级别的东西。

在黑暗中这将是一个完整的镜头,但也许这篇文章可能是相关的? – 但可能不是那些堆栈跟踪。

我有许多具有自己资源的自定义Windows控件,因此当我创建许多控件时会出现此错误。 为了解决这个问题,我在我的库中创建了Resource文件,并使用外部资源而不是组件代码上的资源。 之后,我的exception消失了,已经测试了3次以上打开的表单,这个错误消失了。 所以看起来它是一个解决方案。