[c#] Win32Exception Nicht genügend Speicher ist verfügbar, um diesen Befehl zu verarbeiten



1 Answers

Ihr Programm verliert wahrscheinlich Kernel-Ressourcen. Starten Sie die Diagnose dieses Problems mit Taskmgr.exe. Zeigen Sie + wählen Sie Spalten an, markieren Sie Benutzerobjekte, GDI-Objekte und Anzahl Handle. Führen Sie Ihr Programm aus und beobachten Sie, ob einige davon stetig zunehmen. Sobald einer von ihnen 10.000 erreicht, wird dein Programm sterben.

Mit einer Möglichkeit, das Leck in Aktion zu sehen, können Sie Code kommentieren, um zu sehen, wo das Leck auftritt. Es hat wahrscheinlich etwas mit Ihrem "Haken" zu tun.

Question

Durch meine automatisierte Crash-Sammlung für MaxTo bekam ich folgenden Absturzbericht :

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)

Ein weiterer Stacktrace:

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)

In diesem letzten Stack-Trace gibt es überhaupt keinen Verweis auf MaxTo, und 90% der Abstürze, die ich erhalte, sind mit Stack-Spuren ähnlich den obigen.

Im Netz herumlesend finde ich, dass dieser Fehler üblich ist, wenn Sie vergessen, Variablen freizugeben oder zu verwerfen. Wenn ich durch mein WndProc , in dem das Problem manchmal WndProc scheint, kann ich keinen einzigen Ort finden, an dem sich Referenzen auf Objekte befinden. Alle bis auf eine der Variablen sind lokal für WndProc und sollten daher beim Beenden der Methode als Garbage-Collection behandelt werden.

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;
    }
}

Ich war nicht in der Lage, den Fehler zu reproduzieren, auch wenn ich das Programm über mehrere Tage laufen ließ.

Meine Annahme ist, dass das System entweder unfragmentiertem Speicher oder GDI-Handles zu wenig ist, aber ich kann das nirgendwo bestätigen. Es scheint keine gute Dokumentation zu diesem Fehler zu geben.

Irgendwelche Ideen, was es sonst noch sein könnte? Kann ich etwas tun, um diesen Fehler zu vermeiden?

Update : Die Frage wurde wegen des Fehlens einer anständigen Lösung mit mehr Stack-Traces wieder geöffnet. Einfach ignorieren ignoriert das Problem nicht.




Ich hatte viele benutzerdefinierte Windows-Steuerelemente mit eigenen Ressourcen. Wenn ich also viele Steuerelemente erstelle, wird dieser Fehler angezeigt. Um dieses Problem zu beheben, habe ich Ressourcendatei in meiner Bibliothek erstellt und externe Ressourcen anstelle von Ressourcen für meinen Komponentencode verwendet. Danach ist meine Ausnahme weg, bereits mit 3 mal mehr geöffneten Formularen getestet und dieser Fehler weg. Sieht so aus als wäre es eine Lösung.






Related