Quem sou eu

quinta-feira, 3 de dezembro de 2009

Java Heap Dump: Analisando a utilização de memória da sua aplicação Java

No post passado eu falei um pouco sobre o VisualVM mas não falei sobre como fazer o dump do heap do Java em uma máquina monitorada remotamente.
Não dá para fazer isso usando o VisualVM. Você precisa acessar a máquina remota e executar o seguinte comando:
jmap -F -dump:live,format=b,file=dump-heap-java.hprof PID
PID é o número do processo do Java. Para saber o número do processo do Java no Linux, execute o seguinte comando:
ps ax|grep java
Este comando demora um pouco para ser executado, tenha paciência, pois vai depender do seu Heap Size atual. Ele vai gerar um arquivo do tamanho do heap atual. No meu caso, gerou um arquivo de 778 Mb.

Agora que já temos o arquivo de dump, é necessário copiá-lo para a máquina aonde tenha o VisualVM rodando.

Carregue o arquivo no VisualVM usando o Menu File > Load...
Procure o arquivo de dump do heap e abra ele.




Agora que estamos com o dump carregado no VisualVM, vamos tentar encontrar o que está gerando problema de uso de memória na aplicação Java.

Clique na aba Classes e será exibida uma lista com as classes, o percentual de instâncias, a quantidade de instâncias e, o que nos interessa, o tamanho alocado por essa classe.

Vamos ordenar a lista por tamanho, clicando na coluna tamanho.



Veja que o primeiro da lista é o byte[]. Clicando duas vezes nele, será apresentada a aba Instances contendo todas as instâncias que estão usando o byte[] na memória.



Perceba que temos várias instâncias com o mesmo tamanho (16681), o que significa que é a mesma classe que está usando o byte[] e não está desalocando o recurso.

Clique em uma das instâncias e vai abrir na lateral direita a área References na parte inferior. Clique com o botão direito na classe que vai aparecer e em seguida escolha a opção Show Instance.



O resultado irá mostrar o que está ocupando a memória:



No meu caso era um comando SQL de Insert a um banco de dados de teste MySQL. Perceba na imagem que temos o comando SQL completo, separado em vários chars.

Associado a este dump, utilizei o dump dos threads onde vi qual a classe que estava gerando os Threads Blocked. Neste meu caso, o problema estava no servidor de Banco de Dados que estava mau configurado e não estava tendo recursos suficientes para atender a todos os requests.

Utilizando dump de Heap e dump de threads como mostrei no meu post anterior, você conseguirá detectar todos os problemas de gerência de memória da sua aplicação.

Uma outra funcionalidade legal que você pode utilizar no VisualVM é utilizar o JConsole somado ao plugin JTop para monitorar o consumo de CPU por threads para detectar uso excessivo de CPU gerado por algum bug no software, mas isto é assunto para um outro post.

Nenhum comentário:

Postar um comentário