2009-02-14 17 views
11

A través de mi colección accidente automatizado para MaxTo me dieron el siguiente informe de bloqueo:Win32Exception No hay suficiente almacenamiento está disponible para procesar este comando

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) 

Otra 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) 

En esta última traza de la pila que hay no es ninguna referencia a MaxTo en absoluto, y el 90% de los bloqueos que obtengo tienen rastros de pila similares a los de arriba.

Leyendo en la red Creo que este error es habitual si olvida liberar o eliminar variables. Al mirar a través de WndProc, que parece que algunas veces pasa el problema, no puedo encontrar un solo lugar que cuelgue de referencias a cualquier objeto. Todas menos una de las variables son locales para WndProc y, por lo tanto, deberían ser basura cuando el método finaliza.

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

No he podido reproducir el error, incluso mientras se ejecuta el programa durante varios días.

Mi suposición es que el sistema tiene poca memoria no fragmentada o identificadores GDI, pero no puedo confirmarlo en ninguna parte. No parece haber ninguna buena documentación sobre este error.

¿Alguna idea de qué más podría ser? ¿Puedo hacer algo para evitar este error?

actualización: La pregunta se volvió a abrir con más trazas de pila, debido a la falta de una solución decente. Simplemente ignorarlo no resuelve el problema.

+0

No está relacionado con la pregunta, pero ¿cómo se recopilan los informes de fallos? – Giorgi

+0

Utilizando Fogbugz BugzScout (Google it) y un controlador de error global escrito a medida en el programa. No es muy difícil. –

+0

¿Hay algo informado en el registro de eventos de la aplicación Windows en el momento del error? –

Respuesta

11

Fuga o uso de muchos objetos/identificadores de GDI. Esos podrían causar una escasez de recursos. Es posible que no pueda reproducirse porque sus usuarios pueden tener otros programas pesados ​​de recursos de GDI en ejecución o usar Terminal Server, en cuyo caso tienen que compartir algo del montón con los otros usuarios. Consulte System Error. Code: 8. Not enough storage is available to process this command

Here Puede leer sobre la herramienta Desktop Heap Monitor para diagnosticar problemas de pila de escritorio.

Here y here y here son herramientas de detección de fugas GDI.

+0

Esto debe ser. Supongo que este bloqueo fue causado por otros programas que filtran identificadores de GDI. El monitoreo de mi programa mostró que no hay fugas allí. –

+0

¿Has intentado aumentar el montón de escritorio? Mi experiencia es que este error ocurre con mayor frecuencia en los sistemas de Terminal Server donde partes del montón de escritorio se comparten entre los usuarios. Esto podría explicar por qué este error ocurre más a menudo en esos casos. –

+0

El problema es que nunca ha sido reproducible en ninguna de mis computadoras, por lo que no tengo nada para reproducirlo. Estoy agregando más recopilación de datos al análisis de bloqueos, pero pasará bastante tiempo antes de que tenga datos más detallados. –

5

Su programa probablemente esté perdiendo recursos de kernel. Comience a diagnosticar este problema con Taskmgr.exe. Ver + Seleccionar columnas, verificar objetos de usuario, objetos GDI y Recuento de control. Ejecute su programa y observe si alguno de estos aumenta constantemente. Una vez que uno de ellos llegue a 10,000, su programa morirá.

Con una forma de ver rápidamente la fuga en acción, puede comenzar a comentar el código para ver dónde ocurre la fuga. Probablemente tiene algo que ver con su "gancho".

1

Probablemente el problema no esté en su WndProc, la razón por la que lo ve en las pilas de llamadas es porque prácticamente todo lo relacionado con GUI en Windows pasa por el procedimiento de ventana de WIN32. Anularlo en su control simplemente le da un punto de enlace para procesar cosas de bajo nivel antes de que se realice el procesamiento de .NET Framework de nivel superior.

Esto va a ser un completo en la oscuridad, pero quizás this post podría ser relevante? Sin embargo, probablemente no con esos rastros de pila.

+0

No veo cómo sería relevante, ya que no puedo ver la publicación que se vinculó a la producción de este error Sin embargo, la ventana principal de MaxTo tiene paneles anidados, apenas cerca de 12-15 niveles de profundidad, a menos que el usuario se esté volviendo loco con sus configuraciones :) –

+0

@Vegard: los rastreos de la pila probablemente se verían diferentes si era el problema ¿Hay alguna forma de que obtengas rastros de pila Win32 completos y no solo el rastreo .net? – snemarch

+0

No lo creo tan fácilmente. Nunca he podido reproducir en mis propias máquinas. El seguimiento de la pila es simplemente del objeto Exception, no tengo idea de cómo obtener la stacktrace de Win32 (y tendría que proporcionarle al usuario una compilación personalizada después de averiguar cómo obtenerla desde .NET). –

0

Tenía muchos controles personalizados de Windows con recursos propios, así que cuando creo muchos controles aparece este error. Para solucionar este problema, Creé un archivo de recursos en mi biblioteca y utilicé recursos externos en lugar de recursos en el código de mi componente. Después de eso, mi excepción se ha ido, ya probó con formularios 3 veces más abiertos y este error desapareció. Parece que es una solución.

Cuestiones relacionadas