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