1. jmap: magia de linha de comando
O coletor de lixo automático — é, claro, ótimo. Mas até aplicativos Java podem “vazar” (OutOfMemoryError), funcionar devagar ou apresentar travamentos inesperados por uso incorreto de memória. As causas podem ser diversas:
- Vazamentos de memória (memory leaks): objetos que deveriam ter sido removidos continuam “vivos”.
- Volumes de dados grandes demais em coleções.
- Erros na lógica de cache.
- Recursos não liberados (por exemplo, threads, arquivos).
Sua tarefa — aprender a encontrar rapidamente esses problemas. Caso contrário, você corre o risco de se tornar não um programador, mas um “desenvolvedor de bugs”!
O que é o jmap?
jmap — é uma ferramenta que faz parte do JDK padrão. Ela permite obter um “instantâneo” (heap dump) da memória de um processo Java em execução. Esse instantâneo pode ser aberto em outras ferramentas para ver quais objetos ocupam memória, quantos são e quem faz referência a eles.
Heap dump — é como uma fotografia do seu heap: todos os objetos que estão nele, seus tipos, relações e tamanhos.
Como usar o jmap
Encontre o PID do processo
Primeiro é preciso saber o identificador do processo (PID) em que seu aplicativo Java está em execução. Há várias maneiras de fazer isso:
Pelo jps (outra ferramenta do JDK):
jps -l
Você verá a lista de processos Java e seus PIDs.
Pelo Gerenciador de Tarefas (Task Manager) ou ps no Linux.
Capture o dump de memória
jmap -dump:format=b,file=heap.bin <PID>
- format=b — formato binário (adequado para análise).
- file=heap.bin — nome do arquivo onde o dump será salvo.
- <PID> — identificador do processo.
Exemplo:
jmap -dump:format=b,file=heap.bin 12345
O que fazer com o heap dump?
Normalmente o dump é analisado em ferramentas gráficas (por exemplo, jvisualvm ou Eclipse MAT), porque procurar objetos manualmente em um arquivo binário já é nível avançado e um pouco de masoquismo.
Outros recursos do jmap
Ver estatísticas de memória:
jmap -heap <PID>
Mostra informações do heap: tamanho, GC em uso, estado.
Lista de classes:
jmap -histo <PID>
Exibe estatísticas por classe: quantos objetos de cada tipo, tamanho total.
Exemplo de saída:
| # | Objeto | Qtd. | Bytes |
|---|---|---|---|
| 1 | |
1200 | 48000 |
| 2 | |
1000 | 32000 |
| 3 | |
200 | 12800 |
Isso já dá uma noção: se de repente você tem milhões de objetos de algum tipo — é motivo para investigar.
2. jvisualvm: analisador visual de memória
jvisualvm — é um programa gráfico incluído no JDK (veja na pasta bin). Ele permite conectar-se a processos Java locais (e às vezes remotos), monitorá-los em tempo real, capturar heap dump, ver estatísticas de memória, threads, GC, CPU e até perfilar a execução do código.
Se você gosta de clicar com o mouse e ver gráficos bonitos — esta é a sua ferramenta.
Como iniciar o jvisualvm
No terminal (ou por atalho no Windows):
jvisualvm
Abrirá uma janela onde você verá a lista de todos os processos Java locais.
Principais funções do jvisualvm
Monitoramento de memória em tempo real
- Selecione o processo na lista à esquerda.
- Vá para a aba Monitor.
- Você verá gráficos de uso de heap, CPU, quantidade de threads e classes.
Exemplo:

Heap Dump (Instantâneo de memória)
- No painel Monitor clique em Heap Dump.
- Após alguns segundos aparecerá uma aba com a análise do dump.
- Você verá a lista de todas as classes, a quantidade de objetos e o tamanho total.
Busca por objetos “pesados”
- Ordene por tamanho ou quantidade.
- Se você notar que algum tipo (por exemplo, ArrayList ou String) ocupa memória demais — é motivo para investigação.
Análise de referências (Reference Graph)
- Clique na classe — você verá quem referencia os objetos dessa classe.
- É possível chegar à raiz: por que o objeto não é coletado pelo GC.
Análise de threads
- A aba Threads — exibe todas as threads e seus estados.
- É possível identificar threads “travadas” ou ativas demais.
Profiling
- A aba Profiler — permite medir quais métodos consomem mais tempo ou memória.
- Isso já é uma análise mais profunda, mas para encontrar vazamentos de memória os primeiros passos são suficientes.
3. Prática: analisando um vazamento de memória
Exemplo de código com vazamento
import java.util.ArrayList;
import java.util.List;
public class MemoryLeakDemo {
// Coleção estática — clássico do gênero!
private static final List<String> bigList = new ArrayList<>();
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 1_000_000; i++) {
bigList.add("Linha número " + i);
if (i % 100_000 == 0) {
System.out.println("Adicionado: " + i);
Thread.sleep(500); // Damos tempo para análise
}
}
System.out.println("Pronto! Não feche o aplicativo, abra o jvisualvm.");
Thread.sleep(600_000); // 10 minutos — tempo para análise
}
}
O que está acontecendo?
- Criamos uma lista estática e adicionamos a ela um milhão de strings.
- Após terminar as inserções o programa “fica parado” (aguarda), para que você possa se conectar a ele com as ferramentas de análise.
Análise via jvisualvm
- Execute o programa.
- Abra o jvisualvm e selecione o processo.
- Na aba Monitor, observe o gráfico de memória.
- Se estiver tudo bem, a memória deve ser “liberada” após o GC.
- Se houver vazamento, a memória só aumenta.
- Faça um Heap Dump.
- Veja quais objetos ocupam mais memória.
- No nosso caso — java.util.ArrayList e java.lang.String.
- Clique no objeto — veja quem o referencia.
- Você verá que é o campo estático bigList.
Como corrigir?
- Remova elementos desnecessários das coleções e limite seu crescimento.
- Defina como null as referências a objetos pesados quando eles não forem mais necessários.
- Não mantenha coleções grandes em static se elas não forem necessárias o tempo todo.
4. Outras ferramentas: Eclipse MAT, jconsole
Eclipse Memory Analyzer (MAT)
Eclipse MAT — é uma ferramenta gratuita e poderosa para análise de heap dump. Com ele é possível ver quais objetos ocupam memória e quais deles retêm outros — o chamado retained set. Isso permite identificar com precisão onde o vazamento está escondido.
A ferramenta consegue gerar relatórios detalhados de objetos suspeitos (leak suspects) e lida tranquilamente até com dumps gigantes de vários gigabytes.
Funciona de forma simples: você captura um dump de memória com o jmap ou o jvisualvm, abre-o no MAT, clica no botão Leak Suspects Report — e obtém um relatório pronto com os potenciais problemas já destacados.
jconsole
jconsole — é uma ferramenta simples e prática para observar a JVM em tempo real. Ela mostra quanta memória está sendo usada, quão carregado está o processador, quantas threads estão ativas e como o coletor de lixo se comporta.
Ao contrário de ferramentas mais avançadas como o VisualVM, o jconsole não analisa heap dump, mas é ótimo para diagnóstico rápido — quando você precisa entender de relance o que está acontecendo dentro do aplicativo.
5. Erros comuns na análise de memória
Erro nº 1: você captura o dump do processo errado. Muitas vezes há vários aplicativos Java rodando na máquina e é fácil confundir o PID. Verifique com o jps e certifique-se de que está analisando o seu programa.
Erro nº 2: esperar ver “vazamento” onde ele não existe. O GC pode não remover objetos imediatamente — às vezes a memória só é “liberada” após um Full GC. Não entre em pânico se após uma iteração a memória não foi liberada — observe a tendência.
Erro nº 3: desconsiderar a influência de objetos estáticos/em cache. Muitos vazamentos estão relacionados a objetos armazenados em campos static ou coleções globais. Verifique quem referencia os objetos “pesados” — muitas vezes é algo static.
Erro nº 4: não usar profiling ao longo do tempo. Heap dump — é bom, mas às vezes é importante observar o crescimento da memória ao longo do tempo (gráficos no jvisualvm). Se a memória cresce de forma consistente — há motivo para investigação.
Erro nº 5: não remover listeners/handlers de eventos. Se você registrou um listener em um evento mas não cancelou o registro — o objeto continuará “vivo” na memória, mesmo que você não o utilize mais.
Dica: Não tenha medo de experimentar as ferramentas! Capture dumps, veja os gráficos, clique nos objetos — só assim você vai “sentir” a memória do seu programa e encontrar problemas rapidamente.
GO TO FULL VERSION