Utilizando o EurekaLog para capturar Memory Leaks em aplicações Delphi

Durante o desenvolvimento e manutenção de sistemas de software, por melhor que os desenvolvedores possam ser, erros podem ser cometidos. Um dos erros mais difíceis de serem detectados são os chamados Memory Leaks, principalmente por não causarem erros aparentes na execução dos programas, mas nem por isso são menos destrutivos quando não tratados.

Memory Leaks, ou “Vazamento de Memória”, é um problema que ocorre quando porções de memória utilizadas pelo programa não são liberadas depois de utilizadas. Isso faz com que o programa passe a usar mais e mais memória, nunca liberando, e pode por fim consumir toda a memória RAM, causando graves problemas ao sistema (ex: lentidão, travamentos, erros de execução, etc). Esse problema é particularmente grave em sistemas que são executados por longos períodos de tempo, como serviços, aplicações para servidores, drivers de dispositivos, sistemas embarcados, etc.

Portanto, vamos demonstrar como podemos capturar esse problema em nossas aplicações Delphi, usando a ferramenta Eureka Log (versão trial disponível em https://www.eurekalog.com/ ). Usarei nesse artigo o Delphi 7 com o EurekaLog 7. Vale notar também que até o momento de escrita desse artigo, o EurekaLog é compatível com Delphi 3 em diante até o Delphi XE6.

Antes de instalar o EurekaLog, feche quaisquer Delphis abertos. Instalar o EurekaLog é bem simples (inclusive está em português), não vou me alongar muito nesse ponto, apenas gostaria de destacar que é possível escolher para quais versões de Delphi presentes no sistema você deseja instalar o EurekaLog.

Depois de instalado, ao abrir o Delphi, notem que foi criado mais um item de menu chamado “EurekaLog”. Porém, não é nesse menu que vamos encontrar as opções que iremos usar. Na verdade, há mais um item de menu que foi criado, dessa vez dentro do menu “Project”, o “EurekaLog Options”. Isso deve-se ao fato de o EurekaLog armazenar suas configurações individualmente para cada projeto.

Ao entrar nessa tela, veja que a princípio o EurekaLog encontra-se desativado, portanto devemos ativá-lo marcando “Activate EurekaLog”. Certifique-se de que em “Project Type” esteja selecionado “VCL Forms Application”.

Entre na seção “Memory Problems” e certifique-se de estar marcado a opção “Catch memory leaks”, e clique em OK.

Depois disso dê um Build em seu projeto (menu Project --> Build). É isso, tudo pronto para detectar os memory leaks do seu projeto!

Para demonstração, vou deixar como anexo desse artigo um pequeno projeto com botões que causam memory leaks de duas formas bastante comuns de ocorrer. A primeira forma é não “dar Free” no final de uso de uma instância de objeto. A segunda forma é criar duas instâncias e atribuir as duas à mesma variável, fazendo com que a primeira instância tenha sua referência perdida. Para fins didáticos, deixei nesse projeto o EurekaLog desativado, para ativar siga as etapas já citadas.

Agora para detectar os memory leaks, execute sua aplicação e use-a da maneira que achar conveniente. Procure usar os recursos que você desconfia que está causando memory leaks. No caso da demonstração, clique nos botões algumas vezes. Ao fechar o aplicativo, caso haja detecção de leaks, será aberto uma mensagem de erro, informando que o aplicativo contém erros. Se tiver escrito “Application has leaked memory”, encontramos memory leaks.

Para abrir um relatório dos leaks encontrados, clique no “click here” da mensagem. Será aberta uma tela enumerando todos os memory leaks encontrados, tipo, tamanho, quantidade, dentre inúmeras outras informações. Em cada leak, há toda a “call stack” do momento da detecção do leak, e essa é a parte mais útil, pois aqui podemos descobrir o ponto exato da sua aplicação que está causando o leak. Para isso, procure na coluna Procedure/Method nomes de rotinas que lhe sejam familiar em relação ao seu projeto.

Ao dar clique-duplo na linha, o EurekaLog lhe levará ao Delphi na linha da rotina que causou o memory leak.

Para corrigir o memory leak ainda depende do desenvolvedor identificar e corrigir dentro dessa rotina a causa do leak (no caso do exemplo, remover a dupla instanciação).

Por fim, algumas observações: ao entregar releases do seu produto aos seus clientes, desative antes o EurekaLog, senão caso aconteça leaks que não foram removidos, ao encerrar a aplicação vai aparecer aquele diálogo do erro por memory leaks. Outro detalhe é mais para os desenvolvedores que utilizam controle de versão (Git, Subversion, Mercurial, etc): o EurekaLog armazena suas configurações junto às configurações do projeto, e isso causa diferenças de versionamento e pode causar alguns problemas. As configurações não são eliminadas mesmo quando desativa-se o EurekaLog, portanto a única maneira que vejo de eliminar as configurações do EurekaLog do seu projeto é desinstalando ele.