O FastMM4 jsem již psal a zmínil jsem se také, že pomáhá detekovat problémy s uvolňováním paměti.
Správný kód vypadá třeba takto:
procedure OKCode;
var
sl: TStringList;
begin
sl := TStringList.Create;
try
sl.Add('Text');
finally
FreeAndNil(sl);
end;
end;
To jistě všichni znáte. Ale sem tam se přihodí, že zapomenete uvolnit paměť, nebo hůře, že se pokusíte uvolnit paměť dvakrát. V druhém případě určitě pomůže FreeAndNil místo volání Free, jelikož FreeAndNil testuje zda není objekt nil (tj. uvolněn) a po uvolnění objekt na nil nastavuje. Ale i zde nám může FastMM4 pomoci.
Ukáži malý kousek kódu:
program Project1;
{$APPTYPE CONSOLE}
uses
FastMM4,
SysUtils, Classes;
procedure TestLeak;
var
sl: TStringList;
begin
sl := TStringList.Create;
sl.Add('Text');
end;
procedure TestDouble;
var
sl: TStringList;
begin
sl := TStringList.Create;
sl.Add('Text');
sl.Free;
sl.Free;
end;
procedure IKnowBug;
var
sl: TStringList;
begin
sl := TStringList.Create;
RegisterExpectedMemoryLeak(sl);
end;
begin
TestLeak;
//TestDouble
//IKnowBug;
end.
Program obsahuje tři procedury: TestLeak (zapomenutí uvolnění TStringList), TestDouble (dvojité uvolnění přes Free), IKnowBug (já vím že je tam chyba).
Nejdříve se sluší říct, že FastMM4 vypisuje chyby jen při běhu z IDE, takže se nemusíte bát, že zákazník si o Vás něco bude myslet. Navíc při běhu z IDE jsou používány speciální metody, které nejsou tak rychlé, ale zato lépe detekují problémy. Program si po startu zjistí zda běží z IDE a podle toho vybere rychlou nebo testovací variantu (ta je mnohem pomalejší).
FastMM4 začleníte do svého programu tak, že jako první unit v .DPR souboru uvedete v sekci uses FastMM4. To je vše (resp. ještě musíte mít někde v cestě FastMM4.pas, FastMM4Messages.pas a FastMM4Options.inc. První je samotný správce paměti, druhý obsahuje texty a třetí slouží pro nastavení chování.
Po spuštění programu nahoře z IDE (znovu to opakuji - jen z IDE) dostanete celkem ukecanou hlášku

K FullDebugMode se za chvilku dostaneme.
Pokud v programu povolíte volání TestDouble, tak bez FastMM4 to asi projde. Ale při používání FastMM4 bude na druhém Free hlášena AV výjimka.
No a třetí procedura IKnowBug ukazuje jak ukázat FastMM4 že tam sice chyba je, ale že s tím momentálně nic nenaděláme.
FullDebugMode
V tomto nastavení paměťový manager generuje při ukončení textový soubor s lepším popisem kde je problém. Samozřejmě tím lepší popis je když mu ho umožníte lépe získat (tj. nastavení linkeru tak aby generoval .MAP soubor, nebo EXE obsahoval TD32 informace - zkuste co Vám bude vyhovovat).
--------------------------------2009/12/15 19:18:27--------------------------------
A memory block has been leaked. The size is: 52
This block was allocated by thread 0x12A74, and the stack trace (return addresses)
at the time was:
40283A [System][@GetMem]
402C11 [System][TObject.NewInstance]
402D7E [System][@ClassCreate]
402C50 [System][TObject.Create]
410728 [Q:\delphi.cz\Project1.dpr][Project1][TestLeak][11]
410831 [Q:\delphi.cz\Project1.dpr][Project1][initialization][37]
7C817077 [Unknown function at RegisterWaitForInputIdle]
The block is currently used for an object of class: TStringList
The allocation number is: 97
Current memory dump of 256 bytes starting at pointer address 7FFA9330:
00 E4 40 00 00 00 00 00 00 00 00 00 D0 2B FA 7F 01 00 00 00 04 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 95 BF 01 80 80 80 80 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a to pro všchny tři reportované problémy, z nichž TStringList je hlavní.
Jedinou změnou je, že v případě FullDebugMode musí být v adresáři aplikace FastMM_FullDebugMode.dll (v balíku FastMM4). Připomínám, že tento mód slouží pro ladění - neměl by být pro uživatele. Aktuální verze (Fast Memory Manager 4.94) umožňuje nastavit i takové chování, kdy když bude nalezena knihovna DLL bude FullDebugMode jinak bude normální.
Obecně přepnutí do FullDebugMode provedete v FastMM4Options.inc nastavením ze
{.$define FullDebugMode}
na
{$define FullDebugMode}
jak radí dialogové okno (to samé i pro LogMemoryLeakDetailToFile, popř. DoNotInstallIfDLLMissing atd.)
FastMM4 a Delphi 2006+
Jak již určitě víte, je FastMM4 standardním memory managerem pro nové Delphi. Ale je tam bez FullDebugMode. Tj. i pro tyto Delphi se vyplatí dát vlastní kopii FastMM4, ale povolit InstallOnlyIfRunningInIDE, tj. bez IDE bude použit integrovaný FastMM4, v IDE bude použita varianta s FullDebugMode (pokud ji teda chcete).
Zrychlení starších Delphi
V distribuci FastMM4 je také náhrada BorlndMM.dll, konkrétně v rámci zipu: FastMM494.zip\FastMM\Replacement BorlndMM DLL\Delphi\Precompiled\for Delphi IDE\Performance\BorlndMM.dll. IDE bude rychlejší a stabilnější.
Jo a slovo FastMM4 bylo použito cca 18x (kdyby to někoho zajímalo).