Pregunta

Nuestra aplicación está fallando en la computadora de un usuario específico con ERROR_NOT_ENOUGH_MEMORY ( "No hay suficiente almacenamiento está disponible para procesar este comando").

aparentemente se está levantando el error en algún lugar profundo en el marco de Delphi VCL que estamos utilizando, así que no estoy seguro de qué función API de Windows es responsable.

¿Es un problema de memoria? Una llamada a GlobalMemoryStatus da la siguiente información:

  • dwTotalPhys - 1063150000 (~ 1 GB)
  • dwAvailPhys - 26735000 (~ 27 MB)
  • dwAvailPage - 1489000000 (~ 1,4 GB)

Parece extraño para mí que Windows dejaría que la memoria física disponible llegar tan baja cuando hay tanto espacio disponible en el archivo de paginación, pero no sé lo suficiente sobre la gestión de la memoria virtual de Windows para saber si esto es normal o no. Es?

Si no recuerdo, a continuación, la cual está siendo golpeado límite de recursos? Por lo que he leído en línea, ERROR_NOT_ENOUGH_MEMORY podría ser el resultado de la aplicación de golpear cualquiera de los varios límites (objetos GDI, objetos de usuario, manijas, etc.) y no necesariamente de la memoria. ¿Hay una lista completa de lo que limita de Windows hace cumplir? ¿Hay alguna manera de saber qué límite es ser golpeado? Traté de Google, pero no pude encontrar ninguna revisión sistemática.

¿Fue útil?

Solución 3

El culpable en este caso era CreateCompatibleBitmap . Aparentemente Windows puede hacer cumplir bastante estrictos límites de todo el sistema de la memoria disponible para mapas de bits dependientes del dispositivo (véase, por ejemplo, este correo lista de discusión ), incluso si su sistema de lo contrario tiene un montón de memoria y un montón de recursos GDI. (Estos límites son al parecer todo el sistema, ya que Windows puede asignar mapas de bits dependientes del dispositivo en la memoria de la tarjeta de vídeo.)

La solución es simplemente usar mapas de bits independientes del dispositivo (DIB) en lugar (aunque éstos no pueden ofrecer tan bien de una actuación). Este artículo KB describe cómo elegir el formato DIB óptimo para un dispositivo.

Otros candidatos para el límite de recursos (a partir de las respuestas de otros y mi propia investigación):

  • recursos GDI (a partir de esta respuesta) - fácilmente controladas con GDIView
  • fragmentación de memoria virtual (de esta respuesta)
  • montón de escritorio - ver aquí o aquí

Otros consejos

todas las posibilidades.

GDI-problemas se pueden monitorizar mediante el GDIView utilidad. Es un solo archivo que los usuarios pueden empezar sin un instalador.

Además, instalar el ProcessExplorer en la máquina en cuestión.

Si no tiene acceso a la máquina, pida al usuario para hacer capturas de pantalla del estado supervisado por las aplicaciones. Muy likeley, esto le dará alguna pista.

Una causa más común de este error que cualquiera de los que ha enumerado es la fragmentación del espacio de memoria virtual. Esto una situación en la que, mientras que la memoria libre total es bastante razonable el espacio libre está fragmentado con varios bits de espacio de memoria virtual que se está actualmente asignado. Por lo tanto, se puede obtener un error de falta de memoria cuando la solicitud de memoria no puede ser satisfecha por un solo bloque contiguo a pesar de ser lo suficientemente libre en total.

Mi respuesta puede ser un poco más tarde, pero, desde mi difunto experiencia con ese mismo tema, haciendo todas las pruebas, ir paso a paso, la creación de DC, liberándolo, utilizando DIBSection en lugar de CompatibleBitmap, utilizando herramientas de fugas GDI / Memoria , etc.

En el extremo (LOL) encontré que:

Me estaba cambiando la prioridad de estos dos llamadas, entonces todo el problema se solucionó.

DeleteDC(hdc);       //do it first (always before deleting objects)
DeleteObject(obj);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top