Detectando vazamentos de memória no Delphi: uma lista definitiva das ferramentas

Detectar vazamentos de memória é uma tarefa muito importante no desenvolvimento em Delphi. Já escrevi sobre isso antes, reforçando que em aplicações servidores como aquelas construídas com o TMS XData, isso é ainda mais importante.

Com a proximidade do lançamento do Delphi 10.4, isso será ainda mais relevante. Um gerenciamento de memória unificado no Delphi vem sendo prometido desde o ano passado e ao que parece, virá nessa nova versão.

Como tudo na vida, essa mudança não é 100% boa ou ruim, há vantagens e desvantagens, mas uma coisa é clara: a forma como a memória é gerenciada será a mesma em todas as plataformas, portanto as formas de detectar vazamentos de memória nas diferentes plataformas serão similares. Pessoalmente eu acho que isso é uma coisa boa. Também é importante notar que isso não significa que teremos mais vazamentos nas aplicações mobile. O mecanismo ARC “antigo” (ainda vigente enquanto escrevo este artigo) também apresenta problemas de vazamentos e, na minha opinião, mais difíceis de detectar, como por exemplo quando lidamos com referências cíclicas.

Mas essa introdução já está longa demais: o humilde propósito deste artigo é ser uma lista atualizada e definitiva de todas as ferramentas que você pode usar para detectar vazamentos de memória no Delphi. O fato de que a forma de gerenciamento da memória será unificado apenas significa que essas ferramentas estão mais relevantes do que nunca: detectar e corrigir vazamentos de memória no Windows irá ajudá-lo ainda mais para que suas aplicações não-Windows não vazem memória também.

Então, vamos à lista!

FastMM (Grátis)

FastMM (ou sendo mais específico, FastMM4) é a ferramenta padrão de-facto para detectar vazamentos de memória no Delphi. O motivo é simples: é o gerenciador de memória default do Delphi, portanto já está incluído e pronto pra usar.

Já que é o FastMM mesmo que aloca e libera a memória da sua aplicação, quem poderia reportar melhor os blocos de memória que não foram liberados? Tudo que você precisa pra começar a usá-lo é adicionar uma única linha de código ao seu projeto:

ReportMemoryLeaksOnShutdown := True;

E voilà, sua aplicação irá mostrar todos os vazamentos de memória quando ela terminar. Se houver vazamentos, uma janela será apresentada listando todos os vazamentos detectados.

Todos os desenvolvedores Delphi deveriam adicionar essa linha nas duas aplicações. Sério. Eu nem sei por que isso não é feito por padrão pelo Delphi, pelo menos tendo a linha envolvida pela diretiva {$IFDEF DEBUG}. Talvez por razões históricas.

Bom, se já está disponível e funciona, por que não terminamos este artigo por aqui e pronto? É que tem alguns detalhes.

O Delphi inclui uma versão reduzida do FastMM4. Ele não possui todos os recursos avançados de depuração e detecção que você precisaria (pra saber, por exemplo, qual linha de código foi alocada a memória que vazou). Pra isso, você tem que usar a versão completa do FastMM4, disponível no repositório público do FASTMM4 no GitHub.

Você também tem que usar uma DLL externa para usar os recursos avançados; não é multiplataforma: só funciona oficialmente no Windows (parece que há uma versão macOS disponível no repositório principal, mas nunca testei). E apesar de ter muitos recursos avançados, pra usá-los você tem que configurar manualmente o arquivo .INC, o que pode não ser muito confortável para alguns usuários.

De qualquer forma, é uma boa ferramenta, a ferramenta “padrão” do Delphi pra detecção de vazamentos de memória. (Nota: o FASTMM5 acabou de ser lançado. Não testamos ele ainda, mas parece que melhorou muito a performance para aplicações multithread, estamos ansiosos para testá-lo com o TMS XData.)

Vantagens

  • Grátis;
  • Código-fonte completo;
  • Incluído no Delphi;
  • Fácil pra começar a usar;
  • Vários recursos avançados.

Desvantagens

  • Somente para Windows;
  • Requer DLL externa para os recursos avançados;
  • Não é amigável pra usar os recursos avançados (não há uma interface-visual);
  • Somente reporta vazamentos de blocos de memória alocados pelo FastMM.

LeakCheck (Grátis)

Delphi LeakCheck é outra excelente opção para detecção de vazamentos de memória. Também é grátis, open source e tem algumas vantagens em relação ao FastMM: é multiplataforma, o que significa que você pode detectar vazamentos diretamente em suas aplicações mobile ou Linux; e integra muito bem com frameworks de teste unitário (mais precisamente DUnit and DUnitX).

A forma de usar também é semelhante à do FastMM: adicione a unit LeakCheck como a primeira unit da cláusula uses do seu dpr, e ele irá se plugar e estará pronto pra uso. Configurar pra uso em teste unitário é um pouco mais complicado, mas isso é esperado e faz parte.

Uma pequena desvantagem é que você estará praticamente por sua conta e risco: o projeto não vem tendo atualizações já há algum tempo (o que não é necessariamente um problema já que ele funciona bem). Mas provavelmente significa que você não conseguirá ajuda diretamente do autor (nunca tentei, pra ser justo). Também não há muita informação sobre ele na internet, encontrei apenas um único artigo que explica como usá-lo, além da descrição no repositório oficial dele no Bitbucket.

Vantagens

  • Grátis;
  • Código-fonte completo;
  • Multiplataforma;
  • Integra bem com bibliotecas de teste unitário (DUnit and DUnitX).

Desvantagens

  • Não há muita informação disponível sobre como usá-lo;
  • Não há atualizações recentes nem suporte oficial;

Deleaker (Comercial)

Delaker é a única ferramenta comercial desta lista que é dedicada exclusivamente a detecção de vazamentos de memória. Isso reflete no produto, que fornece diversas excelentes ferramentas pra isso.

Diferentemente das duas ferramentas anteriores, e similar às seguintes, o Deleaker oferece uma interface visual amigável pra você configurar o ambiente e ver os resultados, que pode ser usada tanto integrada à IDE do Delphi como separadamente. Ele também detecta muitos mais tipos de vazamento de memória: vazamentos de GDI, vazamentos de objetos e handles Windows, em DLLs de terceiros, etc. Justamente por causa disso, ele também oferece opções pra você facilmente ignorar vários tipos de vazamentos – se não fosse isso você iria ter um zilhão de notificações de vazamentos mesmo em aplicações simples.

Outro recurso interessante é a possibilidade de fazer snapshots da memória alocada. Isso permite detectar vazamentos não somente da aplicação como um todo mas em trechos específicos dela.

Vantagens

  • GUI amigável que pode ser usada integrada à IDE do Delphi ou separadamente;
  • Detecta todos os tipos de vazamento de memória;
  • Linha de comando para integração CI;
  • Snapshots do uso da memória;
  • Suporte oficial.

Desvantagens

  • License paga ($99 para Home License, $399 para Single Developer License);
  • Somente Windows;

EurekaLog (Comercial)

EurekaLog é uma ferramenta que já está no mercado há décadas. Não achei nenhuma informação no website a respeito de quando a primeira versão foi lançada, mas a informação mais antiga é do EurekaLog 4.0 que foi lançado em 2002, simplesmente há 18 anos.

Não é uma ferramenta dedicada exclusivamente à detecção de vazamentos de memória. Em vez disso, oferece uma vasta gama de recursos. O objetivo do EurekaLog é detectar vários problemas na sua aplicação – exceções, vazamentos, etc. – do lado do cliente, reportando eles pra você.

Portanto, é uma excelente ferramenta pra melhorar a qualidade do seu software e oferecer um bom suporte aos seus clientes, já que você irá obter informações de vazamentos e erros de todos os seus clientes, em diferentes ambientes, fazendo diferentes operações no seu sistema.

Vantagens

  • Detecta tanto vazamentos de memória como vazamentos de resources;
  • Vazamentos e erros detectados durante o uso pelo cliente são enviados automaticamente a você;
  • Vários outros recursos: relatório de bugs, integração com sistemas de controle de bugs, entre outros;
  • Suporte oficial.

Desvantagens

  • Licença paga ($149 para Professional License, $249 para Enterprise License);
  • Somente Windows;
  • Não oferece recursos muito avançados para detecção de vazamentos de memória especificamente.

madExcept (Comercial)

Costumo dizer que o MadExcept é “primo” do EurekaLog. Ambos estão disponíveis há um tempo parecido (cerca de 20 anos ou mais). Compartilham recursos similares. Têm mais ou menos o mesmo propósito. E assim por diante.

E curiosamente, não há um “vencedor”. Se você procurar na web por comparações entre os dois, vai encontrar várias e não vai chegar a uma conclusão sobre qual é o melhor. Usuários de ambos os produtos estão geralmente satisfeitos e geralmente não podem comentar sobre o concorrente porque nunca usaram. É o meu caso, inclusive. Sou um satisfeito cliente do EurekaLog (apesar de não usá-lo pra detectar vazamentos de memória) e nunca usei o madExcept. Mas poderia simplesmente ser o contrário. Acredito que estaria bem servido com o madExcept também.

Assim, considerei as vantagens e desvantagens do madExcept iguais às do EurekaLog. Talvez a única diferença visível é que enquanto o madExcept é mais barato (existe inclusive uma versão grátis para uso não-comercial), o EurekaLog vem sendo mantido e atualizado com muito mais freqüência.

Vantagens

  • Grátis para uso não-comercial;
  • Detecta tanto vazamentos de memória como vazamentos de resources;
  • Vazamentos e erros detectados durante o uso pelo cliente são enviados automaticamente a você;
  • Vários outros recursos: relatório de bugs, integração com sistemas de controle de bugs, entre outros;
  • Suporte oficial.

Desvantagens

  • Licença paga (€149 para licença com código-fonte completo);
  • Somente Windows;
  • Não oferece recursos muito avançados para detecção de vazamentos de memória especificamente.

AQTime Pro (Comercial)

AQTime é um utilitário top de linha pra auxiliá-lo a melhorar o seu código. É realmente alto padrão, oferecendo não somente recursos avançados pra detecção de vazamentos de memória, (com uma interface visual amigável, monitoramento da memória alocada, snapshots, vazamentos de resources, entre outros), mas também recursos de análise de performance, code coverage, análise de código, entre outros.

É uma ferramenta realmente fantástica, mas tem seus defeitos: é extremamente cara, e está de certa forma em “modo manutenção” – recebe em média uma atualização ou menos por ano, e as novidades são basicamente “suporte à nova versão do Delphi”. Um par de bugs são corrigidos e praticamente não há novos recursos. Ainda assim, não há ferramenta equivalente no mundo Delphi quando se trata de facilidade de uso e recursos poderosos.

Vantagens

  • Detecta vazamentos de memória, resources, GDIs, entre outros;
  • Monitor de alocação de memória em tempo real;
  • Snapshots;
  • Várias outras ferramentas no pacote (performance profiler, code coverage, etc.).

Desvantagens

  • Licença cara ($719 para um node-locked license, $2279 para um node-floating license);
  • Somente Windows.

Nexus Quality Suite (Comercial)

Da mesma forma que acontece entre o EurekaLog e o madExcept, acredito que o Nexus Quality Suite é bem parecido com o AQTime. Ambas as ferramentas fornecem diversas ferramentas para melhorar a qualidade do seu software.

O Nexus Quality Suite oferece detecção de vazamentos de memória e resources, mas também profilers de performance, code coverage e até uma ferramenta de teste de interface visual automatizado.

Eu não testei a ferramenta de detecção de vazamento de memória, então as vantagens e desvantagens serão baseadas apenas no que li do site:

Vantagens

  • Detecta vazamentos de memória e resources;
  • Suporte oficial, fóruns de suporte ativos;
  • Várias outras ferramentas no pacote.

Desvantagens

  • Licença paga (AUD 490, cerca de $300);
  • Somente Windows.

DDDebug (Comercial)

Do site deles: DDDebug é uma coleção de ferramentas de depuração que contém vários módulos: um profiler de memória, um visualizador de threads, um visualizador de módulos, e um tratador de exceções melhorado.

Um aspecto interessante que notei é que abordagem do DDDebug é um pouco diferente: ele fornece as estatísticas de uso da memória imediatamente, de dentro da aplicação. Eu não cheguei a testar mas parece facilitar bastante a detecção de bugs, permitindo que você interaja na aplicação ao mesmo tempo que a analisa.

Também funciona com packages o que é uma vantagem, fornece outras funções além de detecção de vazamentos de memória e, apesar de ser uma ferramenta paga, o preço é bem acessível.

Vantagens

  • Fornece os resultados através de uma interface visual de dentro da sua própria aplicação;
  • Suporta packages;
  • Suporte oficial;
  • Preço acessível (a partir de €59).

Desvantagens

  • Somente Windows.

Spider (Grátis)

O website do Spider lista vários recursos interessantes: análise de exceções, análise de uso da memória em tempo real, vazamentos de memória, análise do call stack, etc.

O problema é que, desta lista, é uma ferramenta que testei uma única vez, e fiquei meio confuso com a interface visual e os resultados obtidos. Eu não consegui usar, mas talvez seja minha culpa. Então está listada aqui, mas não posso dar um parecer justo sobre a ferramenta.

Vantagens

  • Grátis;
  • Código-fonte disponível;

Desvantagens

  • Operação confusa (minha opinião);

Ferramentas não-Delphi

Além das ferramentas acima que são específicas para o Delphi, ou pelo menos também cobrem aplicações Delphi explicitamente – seja integrando ao código-fonte, ou à IDE, etc. – também há ferramentas de uso geral para detecção de vazamentos de memória que podem ser úteis em algumas situações.

Valgrind (Grátis)

O Valgrind é uma ferramenta que possui vários módulos. Um deles é o memcheck, que irá ajudá-lo a detectar vazamentos de memória na sua aplicação.

Eu uso o Valgrind pra detectar vazamentos de memória em aplicações Linux, e na verdade é muito simples de usar: apenas execute o utilitário valgrind e passe via parâmetro de linha de comando o caminho da aplicação que você quer testar. O Valgrind irá executar a aplicação e ao final dela irá fornecer um relatório detalhado incluindo os vazamentos de memória. Claro que há várias opções na linha de comando que permitem a você salvar os resultados em arquivo, escolher o tamanho do call stack reportado, o detalhamento das detecções, etc.

Instruments (Grátis)

Apple Instruments é uma ferramenta poderosa e flexível para análise de performance e teste de aplicações, fazendo parte do conjunto de ferramentas do Xcode. Entre outras coisas, pode ser usado para detectar vazamentos de memória em aplicações iOS e macOS. O Adrian Gallero escreveu um excelente artigo no blog da TMS Software sobre como usar o Instruments para detectar vazamentos de memória no iOS. O post já é um pouco antigo, mas acredito que ainda seja válido.

Conclusão

Não há um vencedor. Cada ferramenta tem suas vantagens e desvantagens e é interessante notar que uma não exclui a outra. Na verdade eu uso diversas delas, em diferentes situações e necessidades.

Eu uso o FastMM para detecções de vazamentos de memória no “dia-a-dia”. O LeakCheck em testes unitários. O Deleaker quando quero verificar outros tipos de vazamentos e usar snapshots. O EurekaLog para relatório de bugs das minhas aplicações usadas pelos usuários finals. O AQTime para análise de performance e o Valgrind para detectar vazamentos no Linux. Como você pode ver, todas tem sua utilidade!

O mais importante é: não deixe sua aplicação vazar memória! Se você está apenas começando neste assunto, tudo que você tem que fazer é:

ReportMemoryLeaksOnShutdown := True;

Adicionar a linha acima ao seu projeto e começar a detectar vazamentos de memória!

(Você conhece alguma outra ferramenta que deveria estar na lista? Você tem uma opinião diferente sobre alguma das ferramentas listadas? Deixe seu comentário e compartilhe seu conhecimento para fazer dessa lista a lista definitiva sobre o assunto. Ela será atualizada frequentemente à medida que soubermos de mais informações).

2 comentários em “Detectando vazamentos de memória no Delphi: uma lista definitiva das ferramentas”

Deixe um comentário