Translate

quarta-feira, 2 de janeiro de 2008

Identificação de Memory Leaks com FastMM

O Vazamento de Memória (Memory Leak) acontece quando o programador precisa alocar memória para execução de uma determinada rotina e não libera, isso caracteriza falha e pode comprometer o funcionamento da aplicação, então cabe a nós identificar e corrigir.

Uma forma de reduzir os vazamentos é utilizar um gerenciador de memória durante toda fase de desenvolvimento. A partir do Delphi 2006, o gerenciador padrão vem sendo o FastMM onde pode ser baixado no sourceforge.net, inclusive com código-fonte (versão 4.78 de 416kb).

Como utilizar o FastMM?
  • Descompacte o FastMM em c:\dev\FastMM;
  • Crie um novo projeto Win32, salvando em c:\dev\TesteML;
  • Na Unit1 do projeto, será necessário ativar o relatório no qual informará se houve ou não vazamento em nossa aplicação. Esse relatório será mostrado após o termino da aplicação laçada pela IDE do Delphi (F9), veja o código abaixo:
initialization
  ReportMemoryLeaksOnShutdown := DebugHook <> 0;
  • No evendo OnCreate do Form1, crie duas StringList e em seguida execute a aplicação, veja o código abaixo:
procedure TForm1.FormCreate(Sender: TObject);
var
  SL1, SL2: TStringList;
begin
  SL1 := TStringList.Create;
  SL2 := TStringList.Create;
  SL1.Add('Teste com FastMM na StringList SL1');
  SL2.Add('Teste com FastMM na StringList SL2');
end;


Após finalização do aplicativo, uma mensagem é exibida informando os vazamentos ocorridos: 2 objetos do tipo TStringList (TStringList x 2). Até esse ponto, estamos usando as configurações padrão do FastMM do Delphi 2006 e 2007.

Identificação dos Memory Leaks:
  • No Delphi, clique em Projet-> Options ou (Shift+Ctrl+F11):
  • Em Directories/Conditionals informe o caminho: ..\FastMM;
  • Em Directories/Conditionals informe a Conditional Defines: EnableMemoryLeakReporting;
  • Copie o arquivo FastMM_FullDebugMode.dll localizado em C:\dev\FastMM\FullDebugMode DLL\Precompiled para a pasta C:\dev\TestML onde está o executável;
  • Abra o arquivo FastMM4Options.ini que está na pasta C:\dev\FastMM\ e faça suas configurações, nele você poderá fazer diversas combinações, é auto-explicativo, basta incluir/excluir o ponto final (".") para habilitar ou desabilitar as diretivas de compilação. As mais significantes são: FullDebugMode e ClearLogFileOnStartup;
  • Execute a aplicação e aguarde a nova mensagem como essa abaixo:

Na pasta do projeto, abra o arquivo de log gerado pelo FastMM chamado: Project1_MemoryManager_EventLog.txt

--------------------------------2008/1/3 0:41:23--------------------------------
A memory block has been leaked. The size is: 52

Stack trace of when this block was allocated (return addresses):
404AF0 [FastMM4Messages.pas][System][System.@LStrAsg][138]
419EDB [Classes][Classes.TStringList.InsertItem]
44E13B [Forms][Forms.TCustomForm.DoCreate]
44DD93 [Forms][Forms.TCustomForm.AfterConstruction]
403FF8 [FastMM4Messages.pas][System][System.@AfterConstruction][138]

The block is currently used for an object of class: Unknown

The allocation number is: 314

Current memory dump of 256 bytes starting at pointer address 1399600:
01 00 00 00 22 00 00 00 54 65 73 74 65 20 63 6F 6D 20 46 61 73 74 4D 4D 20 6E 61 20 53 74 72 69
6E 67 4C 69 73 74 20 53 4C 32 00 00 CD 39 31 FC 80 80 80 80 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
. . . . " . . . T e s t e c o m F a s t M M n a S t r i n g L i s t S L 2
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
--------------------------------2008/1/3 0:41:23--------------------------------
This application has leaked memory. The small block leaks are (excluding expected leaks registered by pointer):

29 - 36 bytes: Unknown x 2
37 - 52 bytes: String x 2
53 - 68 bytes: TStringList x 2

Note: Memory leak detail is logged to a text file in the same folder as this application. To disable this memory leak check, undefine "EnableMemoryLeakReporting".

Com o log gerado pelo FastMM, é possível identificar os vazamentos através do seu conteúdo, porém nem sempre é possível acabar com eles devido alguns serem gerados por componentes de terceiros e quando isso ocorrer, vale a pena escrever comunicar e passar a dica adiante.

Ah, para corrigir esse projeto de exemplo, uma forma é a seguinte:
procedure TForm1.FormCreate(Sender: TObject);
var
  SL1, SL2: TStringList;
begin
  SL1 := nil;
  SL2 := nil;
  try
    SL1 := TStringList.Create;
    SL2 := TStringList.Create;
    SL1.Add('Teste com FastMM na StringList SL1');
    SL2.Add('Teste com FastMM na StringList SL2');
  finally
    SL1.Free;
    SL2.Free; 
  end;
end;


Um comentário:

Anônimo disse...

Obrigado pelas dicas!

Postar um comentário

Deixe seu comentário aqui.