Memory leaks en delphi


 

¿Qué es un memory leak?

Un memory leak ocurre cuando un bloque de la memoria del ordenador no se libera, debido a un fallo del programa que se está ejecutando en ese momento, es decir en un determinado momento del programa necesitamos reservar un conjunto de bytes para almacenar datos o para hacer un cálculo, cuando se termina la operación tendremos que liberar ese bloque de bytes para que lo pueda usar otro módulo de nuestro programa

¿Que ocurre si no se libera?

Si vamos reservando bytes sin liberarlos al final agotaremos la memoria disponible del PC hasta llegar un momento en el que se bloqueará.

Esto provoca que el resto de las aplicaciones se ejecuten más lentamente, ya que cada vez tienen menos memoria disponible, el PC irá más lento.

Esto causa que algunas aplicaciones no lleguen a abrirse ya que no disponen de la memoria suficiente para su correcto funcionamiento.

¿Que tipo de liberación de memoria existe?

Puede ser manual o automática.

Manual:

En Delphi lo hacemos con la instrucción  Free / FreeAndNil  / Destroy  / Release (seguramente se me olvida alguna instrucción ...)

Automática:

En algunos lenguajes como java se utiliza lo que es un "recolector de basura".

También se utiliza un "conteo de referencias" que va contando el número de referencias a la zona bloqueada y cuando llega a 0 libera la memoria. Esto tiene un problema y es que si las referencias forman un ciclo la memoria no se liberará nunca.

Ejemplos de buenas prácticas

//CODIFICACIÓN INCORRECTA (No se libera la variable fich)

procedure obtenerdatos;
var
fich:tstringlist;
lista:string;

begin

lista:='';

fich:=tstringlist.create;

        for i:=1 to fich.count-1 do
        begin
        lista:=lista+fich.strings[i];
        end;

end;


//CODIFICACIÓN CORRECTA (siempre se va a liberar la variable fich)

procedure obtenerdatos;
var
fich:tstringlist;
lista:string;

begin

lista:='';

fich:=tstringlist.create; //siempre antes del try
try

        for i:=1 to fich.count-1 do
        begin
        lista:=lista+fich.strings[i];
        end;

finally
  fich.free;
end;

En algunos casos en el evento OnClose del Form también puedes poner "fich.free", pero yo prefiero el método anterior.

Otro ejemplo podría suceder cuando cargamos una dll externa usando LoadLibrary. Siempre hay que llamar al final a FreeLibrary para liberar la memoria ocupada.

 var
   dllHandle: THandle;
begin
   dllHandle: = Loadlibrary ('MyLibrary.DLL');
   // hacer algo con esta DLL
   if dllHandle <> 0 then FreeLibrary (dllHandle);
final;

 

Cómo encontrar fugas de memoria en nuestros programas

Mediante la instrucción 
System.ReportMemoryLeaksOnShutdown: = True;

Poniendo esta variable a true, el administrador de memoria irá escaneando el programa a medida que se va ejecutando e informará al usuario cuando el programa termine de las pérdidas de memoria que haya encontrado.

De la siguiente forma:

begin
  Application.Initialize;
  Application.MainFormOnTaskbar: = True;
  Application.CreateForm (TForm1, Form1);
  System.ReportMemoryLeaksOnShutdown: = True;
  Application.Run;
final .

Programas que detectan fugas de memoria

FASTMM
FastMM es en realidad el administrador de memoria incluido con Delphi desde hace algunos años. Es una obra original de Pierre le Riche. Aunque se incluye con Delphi, puede descargar el código fuente completo de SourceForge en http://fastmm.sourceforge.net . Para aprovechar al máximo la función FastMM, debe abrir el archivo FastMM4Options.inc y cambiar alguna directiva de compilación condicional. Este archivo está muy comentado para explicar todos los símbolos. Al desarrollar su aplicación, debe definir los símbolos "EnableMemoryLeakReporting" y "FullDebugMode". 


Memcheck
MemCheck busca pérdidas de memoria, corrupción de memoria, uso de un objeto después de su destrucción, llamadas a métodos en referencias de interfaz que se refieren a un objeto destruido, etc. MemCheck es un programa gratuito, con código fuente.
http://cc.embarcadero.com/item/16059
 

MadExcept
madExcept fue creado para ayudar a localizar memory leaks en su aplicación Delphi. Siempre que haya un bloqueo / excepción en su programa, madExcept lo detectará, analizará, recopilará mucha información útil y le dará al usuario final la posibilidad de enviarle un informe de error completo.


Eurekalog
EurekaLog es la nueva herramienta complementaria que le da a su aplicación Delphi / C ++ Builder (GUI, Consola, Web, ...) el poder de detectar cada excepción, generando un registro detallado de la pila de llamadas (con unidad, clase, método y número de línea), mostrándolo y enviándolo de vuelta por correo electrónico o mensaje web (HTTP-S / FTP).

LeakCheck (gratis)
Delphi LeakCheck es otra gran opción para detectar fugas de memoria. También es gratuito, de código abierto y tiene algunas ventajas sobre FastMM: es multiplataforma , lo que significa que puede verificar fugas directamente en aplicaciones móviles y Linux; y se integra muy bien con los marcos de prueba unitarios (a saber, DUnit y DUnitX ).

La forma de comenzar es similar a FastMM : agregue la unidad LeakCheck como la primera unidad utilizada en su cláusula de usos de dpr, y se agregará y estará lista para usar. Sin embargo, la configuración para las pruebas unitarias es un poco más complicada, pero eso es parte del juego.

Una pequeña desventaja es que para usarlo estás casi solo: el proyecto no ha recibido actualizaciones por un tiempo (lo cual no es necesariamente malo ya que está funcionando). Pero eso significa que probablemente no obtendrá mucha ayuda directamente del autor (nunca lo intenté, para ser justos). Tampoco hay mucha información al respecto en la web , solo encontré un solo artículo que explica cómo usarlo además de la descripción detallada en el repositorio oficial de Bitbucket.

Pros

Gratis;
Código fuente completo;
Plataforma cruzada;
Se integra bien con las pruebas unitarias (DUnit y DUnitX).
Contras

No hay mucha información sobre cómo usarlo;
Sin actualizaciones recientes, sin soporte oficial;

Deleaker

Delaker es una aplicación comercial que se dedica exclusivamente a detectar fugas de memoria . Eso se refleja en el producto, que le proporciona características realmente interesantes para detectar fugas de memoria.

Tiene una interfaz gráfica de usuario amigable para que pueda configurar el entorno y ver los resultados, que se puede usar de forma independiente o integrada en Delphi IDE. También puede detectar muchos más tipos de fugas de memoria : fugas de GDI, fugas de objetos y identificadores de USUARIO de Windows, fugas en API de Windows, en DLL de terceros, etc. Exactamente por eso, proporciona opciones para que usted ignore fácilmente varios tipos de Fugas : si no lo hace, obtendrá una gran cantidad de fugas en una ejecución normal de la aplicación.

Otra característica interesante es la capacidad de tomar instantáneas de la asignación de memoria . Esto le permite detectar fugas no solo durante la vida útil de toda su aplicación, sino en algunas operaciones específicas de la misma.


 




 





No hay comentarios:

Publicar un comentario

Simulación del movimiento de los electrones en un campo electrico

Espectacular simulación realizada con OpenGL del movimiento de los electrones cuando atraviesan un campo eléctrico. Como muestra la image...