João Emilio Dambroz. Tecnologia do Blogger.

Java heap space, Profiler e Memory Leak

segunda-feira, 8 de julho de 2013

Memory Leak

Ou ainda vazamento de memória, é um fenômeno que acontece quando a memória alocada por algumas variáveis dentro do sistema não é liberada após sua utilização. Este problema é muito comum em sistemas em java que possuem más implementações de lists e hashmaps. Certamente com o tempo uma aplicação com este problema trará inviabilidade para o produto pois o mesmo terá uma longevidade reduzida por conta do erro de memória.

Profiler

São aplicações desenvolvidas com a finalidade de monitorar a utilização de recursos de infra-estrutura por parte das aplicações que estão operando em determinada estação. Por meio desta aplicação salvadora no meio arquitetural, é possível identificar em quais pontos do sistema é mais utilizada a memória, ou a capacidade de processamento, ou ainda a leitura de dados em disco.
É crucial o entendimento destes dois termos que mencionei acima, pois em função de memory leaks, e profilers, eu acabei resolvendo um dos problemas mais importantes que tive nestes últimos tempos.

Java heap space

Em certo momento, durante o desenvolvimento de uma aplicação em java, que já estava sendo testada em produção, me deparei com a seguinte situação: durante a apresentação de aceitação do cliente, em uma reunião que aconteceu duas semanas apos a utilização do sistema, fomos surpreendido por uma exceção  de ‘java heap space’  e na seqüência a aplicação deixou de responder. O produto de fato atendia muito bem ao cliente, logo a nossa única opção era, encontrar o problema a qualquer custo.
Fui alocado nesta tarefa que não só tomou meu tempo em corrigir os problemas na aplicação em horário de trabalho como em buscar novas formas de desvendar problemas de memória durante as madrugadas em que perdi o sono.
Deixei um sistema de profiler executando em ambiente de desenvolvimento com vários usuários utilizando para conseguir simular o ambiente de produção, este foi o primeiro passo para encontrar em qual funcionalidade do sistema estava o vazamento de memória. Quanto mais perto eu ficava do local onde ocorria o vazamento de memória parecia que mais longe eu ficava da solução, as classes onde ocorria o erro certamente eram as mais complexas do sistema, uma utilização genérica de classes e atributos em combinação com HQL dinâmica e views, não tive escolha se não descobrir para que servia cada linha de código. Foram nada menos do que três semanas full time analisando o código e debugando com o profiler.
Isso ajudou muito na refatoração do sistema, hoje o código esta muito bem documentado e qualquer um pode dar manutenção ou incluir novas funcionalidades, infelizmente não serviu para que eu pudesse encontrar o vazamento de memória.
A luta continuou por mais duas semanas onde eu havia deixado de lado a parte de back-end e partido para o front onde eu estava certo de que o erro ocorria. Identifiquei que o algoritmo que era utilizado naquela lógica obscura gerava um TreeNode, uma espécie de hash map do PrimeFaces responsável por fazer a ponte entre o java e o jsf. Este era utilizado como resultado de uma consulta de tree view que era exibido em tela.
O problema acontecia pois após gerar o TreeNode e mostrar em tela, a aplicação continuava referenciando os dados do TreeNode naquela variável. Assim toda vez que esta consulta era executada uma nova variável era criada e esta instanciava o resultado de uma nova consulta. Ai fica minha dica, se você utiliza o Primefaces cuidado com a utilização do TreeNode, até hoje não encontrei uma solução elegante para o problema, o pessoal do Primefaces também não
se pronunciou quanto ao assunto.
A solução encontrada foi utilizando a anotação @finalize em um método e atribuindo a variável do TreeNode como null, assim sempre que o usuário encerrasse a sessão a variável voltava a ser nula e a memória da aplicação voltava ao normal.

O detalhe é que no desenvolvimento desta aplicação o framework utilizado não tinha suporte aos componentes do Primefaces e nem mesmo as injeções de dependência do CDI, logo alem de me preocupar com o problema da aplicação, também tinha que pisar em ovos com as soluções que eram adotadas na aplicação para que o restante continuasse funcionando.

Nenhum comentário:

Postar um comentário

 

Compartilhe

twitter facebook orkut linkedin email

Most Reading