Как отследить хитрую утечку памяти с помощью fastMM?

после обновления проекта с Delphi 2007 до Delphi 2009 я получаю неизвестную утечку памяти, до сих пор я пытался отследить ее с помощью fastMM, вот какие отчеты трассировки стека 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

и иногда я получаю это:

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

есть ли лучший способ выяснить, что на самом деле вызывает утечку памяти?

6 ответов


эта утечка памяти была вызвана ошибкой Delphi, QC #67709

Это было исправлено последним обновлением Delphi 2009, неудивительно, что я не смог его исправить.


пока размер просочившегося блока памяти не растет, чем дольше / больше используется ваша программа, то это не проблема. Если у вас есть долгоживущие объекты, которые освобождаются только при завершении приложения, это то же самое, как если бы вы их слили - вся память восстанавливается по окончании (если, конечно, у них нет ресурсов за пределами памяти).

утечки памяти, с которыми вы хотите иметь дело, - это те, которые накапливаются с течением времени или использования. Если это 20 байт каждый раз тогда не потейте.


Я не знаю, есть ли какие-либо утечки в D2009 VCL, поэтому, предполагая, что утечка находится в вашем коде, сначала я бы проверил следующее:

  • есть ли массив или список (из-за @DynArraySetLength) создан в той форме, которая не освобождается при утилизации формы.
  • есть ли функция, которая создает и возвращает некоторый объект, который должен быть освобожден внешним вызывающим, и если у вас есть такая функция, проверьте, освобождает ли вызывающий этот объект.
  • если это не выявить утечка, то вы должны проверить, если каждый объект, который вы создаете в коде формы, уничтожается при уничтожении формы.

IIRC VCL имел несколько очень маленьких утечек, как это, что вы можете игнорировать без особого беспокойства. Это может быть один из них!? Надеюсь, кто-нибудь прояснит этот момент.


Я бы сказал, что у вас что-то происходит в вашей форме onCreate обработчик событий, который растет DynArray.
И что DynArray не выпустили в конце.
Но, не видя кода и не отлаживая его с помощью FastMM, почти невозможно догадаться, что происходит на самом деле.