videos que puedes poner película how hashtags google como adulto delphi garbage-collection memory-management
Fighting Memory Leaks for Dummies

delphi - que - ¿Se puede limpiar la memoria?



youtube add hashtags (7)

Después de aprender de la excelente respuesta de Barry Kelly, intente analizar su proceso utilizando VMMap de Sysinternals, que se puede encontrar here . Esto analiza el uso de memoria de un único proceso con más detalle incluso que Process Explorer: "VMMap es la herramienta ideal para desarrolladores que desean comprender y optimizar el uso de recursos de memoria de su aplicación". También tiene un archivo de ayuda útil.

Estoy trabajando en Delphi 5 (con FastMM instalado) en un proyecto de Win32, y recientemente he estado tratando de reducir drásticamente el uso de memoria en esta aplicación. Hasta ahora, reduje el uso casi a la mitad, pero noté algo cuando trabajaba en una tarea separada. Cuando minimicé la aplicación, el uso de la memoria se redujo de 45 megas a 1 meg, lo que atribuí a la paginación en el disco. Cuando lo restauré y reinicié el trabajo, la memoria subió solo a 15 megas. A medida que continué trabajando, el uso de la memoria lentamente volvió a subir, y al minimizar y restaurar lo devolvió a 15 megas. Así que, en mi opinión, cuando mi código le dice al sistema que libere la memoria, todavía se está reteniendo según Windows, y la recolección de basura real no se activa hasta mucho más tarde.

¿Alguien puede confirmar / negar este tipo de comportamiento? ¿Es posible limpiar la memoria programáticamente? Si sigo usando el programa sin realizar este enjuague manual, me sale un error de memoria después de un tiempo y me gustaría eliminarlo. Gracias.

Editar: Encontré un artículo en about.com que ofrece mucho de esto, así como algunos enlaces y datos para otras áreas de administración de memoria.


El Administrador de tareas no muestra el total que la aplicación ha asignado desde Windows. Lo que muestra (por defecto) es el conjunto de trabajo. El conjunto de trabajo es un concepto que está diseñado para tratar de minimizar el agolpamiento de archivos de página en condiciones limitadas por la memoria. Básicamente, son todas las páginas en memoria que la aplicación toca de forma regular, por lo que para mantener esta aplicación funcionando con una capacidad de respuesta decente, el sistema operativo se esforzará por mantener el conjunto de trabajo en la memoria física.

En la teoría de que al usuario no le importa mucho la capacidad de respuesta de las aplicaciones minimizadas, el sistema operativo ajusta su conjunto de trabajo. Esto significa que, bajo la presión de la memoria física, es más probable que las páginas de memoria virtual propiedad de ese proceso se paginen en el disco (en el archivo de la página) para dejar espacio.

La mayoría de las veces, la mayoría de los sistemas modernos no tienen problemas de búsqueda para la mayoría de las aplicaciones. Una máquina que agita las páginas severamente puede ser casi indistinguible de una máquina bloqueada, con muchos segundos o incluso minutos antes de que las aplicaciones respondan a la entrada del usuario.

Entonces, el comportamiento que está viendo es Windows recortando el conjunto de trabajo en la minimización, y luego aumentándolo con el tiempo a medida que la aplicación, restaurada, toca más y más páginas. No se parece en nada a la recolección de basura.

Si está interesado en el uso de la memoria por una aplicación en Windows, no hay un número más importante, sino más bien un rango de números relevantes:

  • Tamaño virtual : es la cantidad total de espacio de direcciones reservado por la aplicación. El espacio de direcciones (es decir, a lo que apuntan los punteros) puede no estar reservado, reservado o comprometido. La memoria no reservada puede asignarse en el futuro, ya sea mediante un administrador de memoria o cargando archivos DLL (los archivos DLL tienen que ir a alguna parte en la memoria), etc.

  • Conjunto de trabajo privado : son las páginas que son privadas para esta aplicación (es decir, no se comparten entre varias aplicaciones en ejecución, por ejemplo, todas tienen un cambio en una) y son parte del conjunto de trabajo (es decir, son tocadas frecuentemente por el aplicación).

  • Conjunto de trabajo compartible : estas son las páginas del conjunto de trabajo que se pueden compartir, pero que pueden compartirse o no. Por ejemplo, DLL o paquetes (BPL) pueden cargarse en el espacio de memoria de la aplicación. El código para estos archivos DLL podría compartirse en varios procesos, pero si el archivo DLL se carga solo una vez en una sola aplicación, no se comparte. Si el DLL es altamente específico para esta aplicación, es funcionalmente equivalente al conjunto de trabajo privado.

  • Conjunto de trabajo compartido : estas son las páginas del conjunto de trabajo que en realidad se comparten. Uno podría imitar la imagen atribuyendo el "costo" de estas páginas para cualquier aplicación como el monto compartido dividido por el número de aplicaciones que comparten la página.

  • Bytes privados : son las páginas del espacio de direcciones virtuales comprometidas por esta aplicación y que no se comparten (ni se pueden compartir) entre aplicaciones. Prácticamente, cada asignación de memoria realizada por el administrador de memoria de una aplicación termina en este grupo. Solo las páginas que se usan con cierta frecuencia deben formar parte del conjunto de trabajo, por lo que este número suele ser más grande que el conjunto de trabajo privado. Un conteo cada vez mayor de bytes privados indica una fuga de memoria o un algoritmo de larga ejecución con grandes requisitos de espacio.

Estos números no representan conjuntos disjuntos. Son formas diferentes de resumir los estados de diferentes tipos de páginas. Por ejemplo, working set = private working set + shareable working set.

Cuál de estos números es el más importante depende de lo que esté limitado. Si intentaba hacer E / S utilizando archivos mapeados en memoria, el tamaño virtual limitará la cantidad de memoria que puede dedicar a la asignación. Si se encuentra en un entorno restringido de memoria física, desea minimizar el conjunto de trabajo. Si tiene muchas instancias diferentes de su aplicación ejecutándose simultáneamente, quiere minimizar los bytes privados y maximizar los bytes compartidos. Si está produciendo un conjunto de DLL y BPL diferentes, debe asegurarse de que realmente se compartan, asegurándose de que las direcciones de carga no provoquen que entren en conflicto y eviten compartir.

Acerca de SetProcessWorkingSetSize:

Windows generalmente maneja el conjunto de trabajo automáticamente, dependiendo de la presión de la memoria. El conjunto de trabajo no determina si va a golpear o no un error de falta de memoria (OOM). El conjunto de trabajo utilizado para tomar decisiones sobre la paginación, es decir, qué guardar en la memoria y qué dejar en el disco (en el caso de las DLL) o salir de la página al disco (otra memoria comprometida). No tendrá ningún efecto a menos que haya más memoria virtual asignada que memoria física en el sistema.

En cuanto a sus efectos: si el límite inferior se establece alto , significa que el proceso será hostil a otras aplicaciones y tratará de acaparar la memoria, en situaciones de presión de la memoria física. Esta es una de las razones por las que requiere una garantía real, PROCESS_SET_QUOTA.

Si el límite superior es bajo , significa que Windows no intentará mantener las páginas en la memoria física para esta aplicación, y que Windows puede ubicar la mayor parte en el disco cuando la presión de la memoria física aumenta.

En la mayoría de las situaciones, no desea cambiar los detalles del conjunto de trabajo. Por lo general, es mejor dejar que el SO lo maneje. No evitará situaciones OOM. Esos son generalmente causados ​​por el agotamiento del espacio de direcciones, ya que el administrador de memoria no pudo asignar más memoria; o en sistemas con espacio de archivo de página insuficiente para respaldar la memoria virtual comprometida, cuando se agota el espacio en el archivo de página.


El Administrador de tareas no muestra qué está usando realmente tu programa. Muestra el total que el administrador de memoria ha asignado desde Windows. Cuando libera un objeto o desasigna la memoria asignada dinámicamente, se devuelve al administrador de memoria (FastMM) inmediatamente. Si eso pasó o no a Windows es otro asunto. Al administrador de memoria le gusta tener algo de memoria extra para que no tenga que sacar más del sistema operativo cada vez que necesite crear un objeto nuevo. (Esto es algo bueno, y no desea cambiarlo).

Si el uso de la memoria de su programa aumenta continuamente, en lugar de alcanzar un estado estable en algún momento, es posible que desee mirar a su alrededor y ver si está perdiendo memoria en alguna parte. Y como mencionó Mark, Delphi no usa la recolección automática de basura. En caso de que no lo supieras, asegúrate de que estás liberando tus objetos o entregando su propiedad a algo que los liberará cuando ya no sean necesarios.


Esto es lo que usamos en DSiWin32 :

procedure DSiTrimWorkingSet; var hProcess: THandle; begin hProcess := OpenProcess(PROCESS_SET_QUOTA, false, GetCurrentProcessId); try SetProcessWorkingSetSize(hProcess, $FFFFFFFF, $FFFFFFFF); finally CloseHandle(hProcess); end; end; { DSiTrimWorkingSet }


He leído sobre esto antes, pero no tengo experiencia directa. Llamar a WINAPI SetProcessWorkingSetSize () se supone que "soluciona" el problema. De nuevo, no tengo experiencia directa con esto.


Recientemente tuve un problema muy similar con mi programa. Vea mi pregunta: ¿Por qué la memoria de mi programa Delphi continúa creciendo?

A pesar de que estaba convencido de que se trataba de otra cosa, resultó ser una importante pérdida de memoria causada por unos pocos errores en mi código para liberar la memoria.

Antes de hacer cualquier otra cosa, asegúrese de estar liberando toda su memoria correctamente.


Entendamos bien : FastMM4 no pierde memoria, su código sí.

Para estar seguro, ejecute esta instrucción en algún lugar de su aplicación (donde FastMM4 está en la cláusula uses y $define ManualLeakReportingControl se configura ManualLeakReportingControl, en FastMM4Options.inc, por ejemplo):

ReportMemoryLeaksOnShutdown := True;

FastMM4 informará al final si olvidó liberar algo de memoria.

Si desea saber un poco más, puede ver este video de CodeRage 2: Fighting Memory Leaks for Dummies