c# - Win32Exception 存储空间不足,无法处理此命令

标签 c# .net winapi 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, r.X, r.Y, 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 资源繁重的程序或使用终端服务器,在这种情况下,他们必须与其他用户共享一些堆。参见 System Error. Code: 8. Not enough storage is available to process this command

Here您可以阅读有关用于诊断桌面堆问题的桌面堆监视器工具的信息。

Hereherehere是 GDI 泄漏检测工具。

关于c# - Win32Exception 存储空间不足,无法处理此命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/548971/

相关文章:

jquery - JSON 位图数据

c - 通过图像名称获取进程的进程句柄

windows - Hook Win32 API 事件以在桌面完全加载时收到通知

.net - 当我调整标签的大小时,代码垃圾会在新的空白区域短暂显示

c++ - ListView控件中的LVN_ITEMCHANGED优化

c# - 验证英国电话号码(Regex C#)

c# - SqlBulkCopy 和在标识列上具有父/子关系的 DataTables

c# - 保证代码在 C# 终结器中运行

c# - 迭代器和枚举器的区别

c# - 从 MySQL 数据库获取保存为 BLOB 的图像时参数无效