delphi - Cómo rastrear la pérdida de memoria complicada con fastMM?
memory-leaks delphi-2009 (6)
Después de actualizar un proyecto de Delphi 2007 a Delphi 2009 recibo una pérdida de memoria Desconocida, hasta ahora he estado tratando de rastrearlo usando fastMM, esto es lo que reporta la traza de la pila fastMM:
A memory block has been leaked. The size is: 20
This block was allocated by thread 0x111C, and the stack trace (return addresses)
at the time was:
40339E [System.pas][System][@GetMem][3412] 534873 [crtl][_malloc]
56D1C4 [canex.cpp][MidasLib][DllGetDataSnapClassObject][3918]
56D316 [canex.cpp][MidasLib][DllGetDataSnapClassObject][3961]
56D5EE [canex.cpp][MidasLib][DllGetDataSnapClassObject][4085]
562D48 [DBCommon.pas][DBCommon][TFilterExpr.PutExprNode][1583]
408E46 [System.pas][System][DynArraySetLength][20464]
56D5EE [canex.cpp][MidasLib][DllGetDataSnapClassObject][4085]
408E92 [System.pas][System][@DynArraySetLength][20486]
528C1B [Forms.pas][Forms][TCustomForm.DoCreate][3260]
171A1A [GetRawStackTrace]
The block is currently used for an object of class: Unknown
The allocation number is: 302844
Y a veces obtengo esto:
A memory block has been leaked. The size is: 20
This block was allocated by thread 0x111C, and the stack trace (return addresses)
at the time was:
40339E [System.pas][System][@GetMem][3412]
534873 [crtl][_malloc]
56D1C4 [canex.cpp][MidasLib][DllGetDataSnapClassObject][3918]
56D316 [canex.cpp][MidasLib][DllGetDataSnapClassObject][3961]
77DC921A [RtlAnsiStringToUnicodeString]
56D5EE [canex.cpp][MidasLib][DllGetDataSnapClassObject][4085]
7726B8F5 [GetProcAddress]
7726B907 [GetProcAddress]
589B1E [ossrv.cpp][MidasLib][DllGetDataSnapClassObject][3163]
56D5EE [canex.cpp][MidasLib][DllGetDataSnapClassObject][4085]
408E92 [System.pas][System][@DynArraySetLength][20486]
The block is currently used for an object of class: Unknown
¿Hay alguna forma mejor de descubrir qué es lo que realmente está causando la fuga de memoria?
Diría que algo sucede en su controlador de eventos Form OnCreate que está haciendo crecer DynArray.
Y ese DynArray no se lanza al final.
Pero sin ver el código y realmente depurarlo con FastMM, es casi imposible adivinar lo que realmente está sucediendo.
IIRC VCL tenía algunas filtraciones muy pequeñas como esta que puede ignorar sin mucha preocupación. Este podría ser uno de ellos? Espero que alguien aclare este punto.
No sé si hay fugas en D2009 VCL, así que suponiendo que haya una fuga en su código, primero verificaría lo siguiente:
- ¿Hay alguna matriz o lista (debido a
@DynArraySetLength
) creada en ese formulario que no se libera cuando se elimina el formulario? - ¿Hay alguna función que cree y devuelva algún objeto que debería ser liberado por la persona que llama, y si tiene ese tipo de función, compruebe si la persona que llama libera ese objeto.
- si esto no revela una fuga, entonces debes verificar si cada objeto que creas en tu código de formulario se destruye cuando destruyes el formulario.
Siempre que el tamaño del bloque de memoria no haya aumentado, más tiempo / más se utilizará su programa, entonces no es una preocupación. Si tiene objetos de larga vida que solo se liberan cuando finaliza la aplicación, es lo mismo que si los filtrara: toda la memoria se recupera al finalizar (a menos que, por supuesto, manejen recursos más allá de la memoria).
Las pérdidas de memoria con las que desea preocuparse son las que se acumulan con el tiempo o el uso. Si es 20 bytes cada vez, entonces no te preocupes.
La última vez que tuve una desconcertante fuga a lo largo de estas líneas revisé la memoria en bruto del objeto ofensivo, y vi un texto que me mostró qué clase de datos era. Cuando dice que no sabe qué tipo de objeto es el que probablemente significa que no es un objeto en primer lugar, así que observe las cosas dinámicamente asignadas, incluidas las cadenas.
Esta pérdida de memoria fue causada por un error de Delphi, QC # 67709
Fue arreglado por la última actualización de Delphi 2009, no es de extrañar que no haya podido solucionarlo.