Mostrando entradas con la etiqueta source code. Mostrar todas las entradas
Mostrando entradas con la etiqueta source code. Mostrar todas las entradas

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.


 




 





Libro Code Faster in Delphi

 
 En esta entrada de hoy les hablaré del libro "Code Faster in Delphi" de Alister Christie.

Alister Christie es MVP (profesional más valorado) de Delphi, consultor, desarrollador, formador, presentador y escritor de varios libros. Ha dado charlas en simposios y conferencias de Code Rage de ADUG (Australasian Delphi Users Group) durante muchos años. Es Licenciado en Matemáticas e Informática por la Universidad Victoria, Wellington. Vive cerca de Wellington, Nueva Zelanda.

En su canal de YouTube, ha creado muchas horas de tutoriales en video para ayudarnos a aprender la programación de Delphi de manera eficiente y efectiva.

Actualmente está escribiendo una trilogía de libros dedicada a mejorar nuestros hábitos al programar en Delphi y de paso aprender algunos trucos que esconde este magnífico entorno de programación, el primero de esta trilogía de libros es el que hoy os recomiendo.

La palabra que mejor define a Delphi es productividad, con Delphi es fácil construir componentes, es fácil usar esos componentes y hace fáciles las cosas que en otros lenguajes serían complicadas.

Y de eso trata el libro de Alister: mejorar nuestra productividad.  

En él aprenderemos atajos de teclado y trucos de productividad, manejar clases, etc, cómo editar código más rápido, cómo utilizar Code Insight, cómo escribir nuestros propios plugin, conoceremos en profundidad la RTL, los genéricos, programación paralela, trabajaremos con expresiones regulares, FireDAC, también nos enseñará algunas herramientas de terceros como cnPack, ModelMaker, CodeSite, GExpers, etc...

Un libro altamente recomendable y creo que imprescindible en nuestra biblioteca como programadores.

La definición de Alister de su libro es la siguiente:

Me gusta el título de un libro que tiene doble sentido, y este es uno de ellos.
En primer lugar, este libro tiene como objetivo acelerar la programación. Si lees y entiendes el contenido de este libro, ciertamente hará precisamente eso. En segundo lugar es la certeza de que programar en Delphi es más rápido, con lo que estoy totalmente de acuerdo. 
Se pueden crear aplicaciones potentes y útiles en Delphi sin demasiado esfuerzo,
con mucho menos esfuerzo que en otros lenguajes o herramientas.
Para aprovechar al máximo este libro, solo necesitará un conocimiento básico de Delphi,
sin embargo, este libro será útil tanto para principiantes como para expertos. No importa
cuánto tiempo ha estado usando Delphi, tendrá una gran cantidad de "No puedo
creer que Delphi hace eso ! ", y" He perdido tanto tiempo en el pasado haciendo esto manualmente! ”, y,“ ¿dónde estaba este libro hace años? ”. Si yo te hubiese
escuchado antes. Lo tienes ahora, y eso es lo que cuenta.
Este libro no le enseñará los fundamentos de cómo programar.
Este libro no le enseñará los fundamentos del lenguaje Delphi.
Este libro le enseñará a codificar más rápido en Delphi.
Este libro le hará más rápido en la codificación, pero no mejor en la programación en Delphi
- al menos no directamente - ese es mi próximo libro, "Code Better In Delphi".

 

Puedes comprar el libro desde www.learndelphi.tv

Y sus páginas en redes sociales:

Email: alister@learndelphi.tv
YouTube: https://www.youtube.com/user/codegearguru
Web: https://LearnDelphi.tv
LinkedIn: https://linkedin.com/in/alisterchristie/
Twitter: https://twitter.com/AlisterChristie
Facebook: https://www.facebook.com/LearnDelphitv/
Instagram: https://www.instagram.com/christiealister/


Algunos vídeos de Alister:








Tips para programadores de apps

 

 

1) Revisar el consumo de memoria

Uno de nuestros objetivos al programar una aplicación para dispositivos móviles es no desperdiciar el uso de la memoria utilizándola eficientemente y evitando los memory leaks, en mi caso cuando estoy ejecutando el software que he programado, utilizo la siguiente rutina en Android que me va comprobando la memoria disponible actual y la memoria total del dispositivo.

Este procedimiento lo asocio a un componente tTimer para que cada segundo me informe de la situación actual del consumo de memoria.

Después voy abriendo y cerrando Forms varias veces y compruebo antes y después la memoria disponible. Cuando la diferencia es considerable toca revisar el código. Hay que tener en cuenta que el sistema Android es dinámico y en background se van abriendo y cerrando programas que forman parte del sistema operativo que también modifican la memoria disponible del dispositivo.

La rutina que utilizo es la siguiente:

 
USES
Androidapi.JNI.App;

VAR
    MemLibre, MemTotal: STRING;
    Am: JActivityManager;
    Mi: JActivityManager_MemoryInfo;

...

    Am := GetActivityManager;
    Mi := TJActivityManager_MemoryInfo.Create;
    Am.GetMemoryInfo(Mi);
    // bajamemoria := mi.lowMemory;
    MemLibre := (Mi.AvailMem DIV 1048576).Tostring() + 'Mb';
    MemTotal := (Mi.TotalMem DIV 1048576).Tostring() + 'Mb';
    Label2.Text := MemLibre + ' / ' + MemTotal;

2) Evitar el uso de "Release" con el componnte tWebBrowser

Si inserta un componente tWebBrowser (con su propiedad Name: WebBrowser1) no escriba WebBrowser1.Release para liberar memoria al cerrar la app. Esta instrucción está desactualizada y no tiene ningún efecto.

3) Controlar el uso de Form.BringTofront, después del Form.Show

No es necesario poner

Form1.Show;

Form1.BringtoFront;

Con poner Form1.Show es suficiente, ahorra código y evitará problemas cuando tiene muchos forms en la app.

4) Añadir FireDAC.Phys.SQLiteWrapper.Stat

Si usa FireDac, no olvide añadir en el USES de la unit: FireDAC.Phys.SQLiteWrapper.Stat 

Esto se ha activado en la última versión de Rad Studio la 10.4

5) No use Application.Processmessages al programar apps para Android.

 No tiene ningún efecto en el código


6) Optimizar SQLite

6.1) Use el comando Sweep de Firedac para optimizar la base de datos SQLite.

Internamente llama al comando VACCUM de SQLite, haciendo lo siguiente:

Primero copia los datos dentro de un archivo de base de datos a una base de datos temporal. Esta operación desfragmenta los objetos de la base de datos, ignora los espacios libres y vuelve a empaquetar páginas individuales. Luego, SQLite copia el contenido del archivo de base de datos temporal al archivo de base de datos original. Se sobrescribe el archivo de base de datos original.

Esto se hace de la siguiente forma:

Añada un componente llamado tFDSQLiteValidate al form.


 

 

y después escriba:

FDSQLiteValidate1.Sweep;

Recordar que la base de datos sobre la que tengamos que hacer esta operación ha de estar cerrada, en caso contrario salta una excepción.

6.2)  Use LIMIT 1 Cuando sólo quiera obtener una única fila al hacer una consulta.

En estos casos, añadir LIMIT 1 al query puede mejorar significativamente la velocidad. De esta forma la base de datos dejará de escanear resultados en el momento que encuentre uno, en lugar de recorrer toda la tabla o un índice.

6.3)  Indexe los campos de búsqueda.

Si utiliza siempre las mismas columnas para realizar búsquedas, indéxelos para mejorar la velocidad.

6.4) Evite SELECT *

Siempre que se pueda, coloque a continuación del SELECT los nombres de las columnas que use. Si una tabla tiene 2000 columnas no es eficiente hacer un select de las 2000.


 

 

 



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...