FastMM e Delphi 2006
Continuando um tema anteriormente publicado, neste artigo vamos começar a detectar os vazamentos de memória (memory leaks) existentes em nossos aplicativos. (isso se existirem, é claro…)
A partir do Delphi 2006 o gerenciador de memória padrão que acompanha o Delphi passa a ser o FastMM. Quem não trabalha com Delphi 2006 pode baixar o FastMM aqui.
Se você estiver começando agora a desenvolver com Delphi deve estar se perguntando: Tá, e dai? O que é memory leak?
Memory leak é um objeto criado pela aplicação que não foi corretamente destruído.
Você pode simular esta situação criando qualquer objeto no OnCreate do formulário principal da sua aplicação. Exemplo:
procedure TForm1.FormCreate(Sender: TObject);
var
lstVazamento : TStrings;
begin
lstVazamento := TStringList.Create;
try
lstVazamento.Add('Linha 1');
lstVazamento.Add('Linha 2');
lstVazamento.Add('Linha 3');
finally
end;
end;
Execute o aplicativo e feche-o. Você notará que não acontece nada!
Esse teste ridículo foi feito só para você ver como é comum ocorrerem problemas que resultem em vazamentos de memória (memory leaks) como a falta de atenção (nesse caso), a pressa, Control+C / Control+V entre alguns outros.
Agora insira esta linha logo após o begin da sua procedure:
ReportMemoryLeaksOnShutdown := True;
Deixando o código assim:
procedure TForm1.FormCreate(Sender: TObject);
var
lstVazamento : TStrings;
begin
ReportMemoryLeaksOnShutdown := True;
lstVazamento := TStringList.Create;
try
lstVazamento.Add('Linha 1');
lstVazamento.Add('Linha 2');
lstVazamento.Add('Linha 3');
finally
end;
end;
Repita a operação e veja o que acontece após fechar o aplicativo:
Veja que recebemos a notificação do TStringList que criamos e das 3 linhas que adicionamos (String x 3) a ele. A partir dai podemos começar a evitar esse tipo de erro na hora de desenvolvermos aplicativos.
Uma dica importante é você utilizar o bloco try…finally…end; sempre que criar um objeto dinamicamente. Isto evita que ocorra um erro no meio da execução e ele não seja destruído devidamente. Veja os dois exemplos:
Método não apropriado:
procedure TForm1.FormCreate(Sender: TObject);
var
lstVazamento : TStrings;
begin
ReportMemoryLeaksOnShutdown := True;
lstVazamento := TStringList.Create;
lstVazamento.Add('Linha 1');
lstVazamento.Add('Linha 2');
lstVazamento.Add('Linha 3');
lstVazamento.Free;
end;
Método apropridado de utilização:
procedure TForm1.FormCreate(Sender: TObject);
var
lstVazamento : TStrings;
begin
ReportMemoryLeaksOnShutdown := True;
lstVazamento := TStringList.Create;
try
lstVazamento.Add('Linha 1');
lstVazamento.Add('Linha 2');
lstVazamento.Add('Linha 3');
finally
lstVazamento.Free;
end;
end;
Utilizando o bloco try…finally…end; mesmo que ocorra algum erro na execução do procedimento o objeto é destruído. Pelo método não apropriado lstVazamento não seria destruído caso ocorresse algum problema na execução da linha lstVazamento.Add(‘Linha 1′);, por exemplo.
Em tempo: utilizando ReportMemoryLeaksOnShutdown := True; a mensagem ocorrerá sempre que o aplicativo for terminado, inclusive fora do Delphi. Para evitarmos esse situação, substitua o True por DebugHook <> 0; deixando a linha assim:
ReportMemoryLeaksOnShutdown := DebugHook <> 0;
Para quem utiliza outras versões do Delphi isto deve ser configurado no arquivo FastMM4Options.inc.
No próximo artigo abordaremos mais funções do FastMM e configurações do arquivo FastMM4Options.inc para quem utiliza FastMM em versões mais antigas do Delphi. Até mais!