1. JMX (Java Management Extensions): o coração do monitoramento da JVM
Monitoramento é como um check‑up regular para o seu aplicativo. Se o logging pode ser comparado a um diário onde se registra tudo o que já aconteceu, o monitoramento é um conjunto de instrumentos que mostram o estado do sistema neste exato momento: temperatura, pulso, pressão, nível de açúcar e outros indicadores vitais da JVM.
Ele ajuda a entender quanta memória está realmente sendo usada e se há vazamentos, quantas threads estão executando e em que estado elas estão — aguardando, em execução ou bloqueadas. É possível ver com que frequência o coletor de lixo roda, o quão ocupado está o processador e notar a tempo sintomas preocupantes como um crescimento repentino da memória ou do número de threads.
Em resumo, o logging conta o que já aconteceu, enquanto o monitoramento mostra o que está acontecendo agora.
Fundamentos do JMX: o que é e para que serve
JMX é uma tecnologia do Java que permite observar a vida do seu aplicativo por dentro e até controlá‑lo um pouco. Ela funciona por meio de objetos especiais — MBean (Management Bean). Dá para dizer que são “sensores” e “chaves” dentro da JVM: alguns mostram o estado do sistema, outros permitem ajustar algo.
Com o JMX você pode saber quanta memória a JVM alocou agora, quantas threads estão ativas, quanto tempo é gasto na coleta de lixo e muito mais — sem precisar mexer no código ou reiniciar o aplicativo.
Como isso é estruturado
Na JVM já existem, “de fábrica”, muitos MBeans que fornecem informações sobre:
- memória (heap, non-heap);
- coletores de lixo (GC);
- threads;
- classes (quantas foram carregadas, descarregadas);
- e até sobre a própria JVM (versão, parâmetros de inicialização).
JMX é como o painel de instrumentos de um carro. Você vê velocidade, rotações, temperatura do motor — e tudo isso está disponível por meio de sensores padrão (MBeans).
Como acessar o JMX
A maneira mais simples é usar a ferramenta padrão JConsole, que vem com o JDK.
Iniciando o JConsole
- Abra o terminal/linha de comando.
- Execute o comando:
jconsole - Selecione o processo Java que deseja monitorar (por exemplo, seu aplicativo).
O JConsole se conectará à JVM via JMX e mostrará gráficos e tabelas: uso de memória, quantidade de threads, atividade do coletor de lixo etc.
Exemplo: ver memória e threads
No JConsole, abra as abas "Memory" e "Threads". Você verá como muda o volume de memória usada, quantas threads estão vivas agora, quais estão ativas e quais estão esperando.
MBeans personalizados
Você pode criar seus próprios MBeans para monitorar métricas específicas (por exemplo, a quantidade de pedidos processados). Mas isso já é um tópico avançado: os MBeans padrão fornecem muita informação.
2. VisualVM — monitoramento visual e perfilamento
Se o JConsole é o “painel de instrumentos”, o VisualVM é um verdadeiro centro de diagnóstico com raio X, ressonância magnética (RM) e exame de sangue. Ele permite não só monitorar, mas também fazer perfilamento do aplicativo, capturar heap dump, analisar vazamentos e ver quais métodos consomem mais tempo.
Instalação e execução do VisualVM
- O VisualVM vem com o JDK (geralmente como jvisualvm), mas a versão mais recente pode ser baixada em visualvm.github.io.
- É iniciado com o comando:
jvisualvm - Após iniciar, você verá a lista de todos os processos Java em execução na sua máquina.
Conectar a um processo
- Encontre seu processo (por exemplo, Main ou MyApp) na lista.
- Dê um duplo clique nele — uma aba com as informações do processo será aberta.
- Pronto! Agora você vê:
- Uso de CPU e de memória em tempo real.
- Quantidade de threads e seu estado.
- Lista de classes carregadas.
- Possibilidade de capturar heap dump e thread dump.
Principais recursos do VisualVM
Com o VisualVM é possível observar como a memória é usada — tanto heap quanto non-heap. No gráfico dá para ver se o consumo cresce ou se estabiliza. Para testar o trabalho do coletor de lixo, clique no botão "Perform GC" — a JVM tentará limpar a memória imediatamente. Você pode fazer um heap dump (instantâneo da memória) e estudá‑lo para encontrar vazamentos.
A ferramenta também mostra o estado das threads: quantas estão em execução, quais trabalham, aguardam ou estão bloqueadas. Se ocorrer um deadlock, o VisualVM ajuda a detectá‑lo e exibir os bloqueios mútuos.
Para uma análise profunda há o perfilamento: você verá métodos “quentes” que “consomem” mais tempo de CPU ou memória. Isso é útil ao diagnosticar uma queda inesperada de desempenho.
Exemplo: monitorando um miniaplicativo
public class MemoryLeakDemo {
public static void main(String[] args) throws InterruptedException {
List<byte[]> memoryConsumers = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
memoryConsumers.add(new byte[1024 * 1024]); // 1 MB
Thread.sleep(100); // Vamos aguardar um pouco para que o gráfico fique mais suave
}
System.out.println("Pronto! Não se esqueça de conferir no VisualVM :)");
Thread.sleep(60000); // Mantemos o aplicativo aberto para análise
}
}
Agora:
- Execute o programa.
- Abra o VisualVM e conecte‑se ao processo.
- Observe como o uso de memória cresce.
- Capture um heap dump e encontre os arrays que ocupam memória.
3. Java Flight Recorder (JFR): a caixa‑preta da JVM
O que é o JFR
O Java Flight Recorder é uma ferramenta integrada à JVM para coletar eventos detalhados sobre a execução do aplicativo. É a “caixa‑preta”: o JFR registra o que ocorre na JVM para depois encontrar gargalos ou as causas de incidentes.
O JFR coleta:
- eventos de GC;
- informações sobre threads;
- frequência de chamadas de métodos e perfis de tempo;
- pausas e latências;
- exceções e erros.
Como habilitar o JFR
A partir do Java 11+, o JFR já está no OpenJDK.
Inicialização com JFR
java -XX:StartFlightRecording=filename=recording.jfr,duration=60s,settings=profile -jar MyApp.jar
- filename=recording.jfr — onde salvar o registro.
- duration=60s — por quanto tempo gravar.
- settings=profile — nível de detalhamento (default, profile, continuous).
Visualizando os resultados
Para analisar o arquivo .jfr usa‑se o JDK Mission Control (JMC):
- Baixe o JMC: jdk.java.net/jmc
- Abra o arquivo recording.jfr.
- Estude os gráficos, métodos “quentes”, pausas de GC e a atividade das threads.
Exemplo: gravando a “caixa‑preta”
- Inicie o aplicativo com o JFR (veja o comando acima).
- Abra o JDK Mission Control e carregue o arquivo de gravação.
- Avalie os pontos “quentes” de CPU/memória, a frequência das coletas de lixo e a quantidade de threads ativas.
4. Prática: monitorando um aplicativo
import java.util.ArrayList;
import java.util.List;
public class MonitoringExample {
public static void main(String[] args) throws InterruptedException {
List<byte[]> memory = new ArrayList<>();
for (int i = 0; i < 50; i++) {
memory.add(new byte[2 * 1024 * 1024]); // 2 MB
Thread.sleep(500);
}
// Iniciamos uma thread
new Thread(() -> {
while (true) {
try {
Thread.sleep(1000);
System.out.println("A thread em segundo plano está em execução...");
} catch (InterruptedException e) {
break;
}
}
}).start();
Thread.sleep(20000); // Mantemos o aplicativo aberto para monitoramento
}
}
Ações:
- Execute o programa.
- Abra o VisualVM, encontre o processo e observe o gráfico de memória e as threads.
- Tente capturar um heap dump e um thread dump.
- Para avançados: inicie com o JFR e veja os resultados no JMC.
5. Dicas úteis
Tabela comparativa de ferramentas de monitoramento
| Ferramenta | Para que serve | Como iniciar | Particularidades |
|---|---|---|---|
| JConsole (JMX) | Métricas básicas da JVM, threads, GC | |
Simples, vem no JDK |
| VisualVM | Monitoramento, perfilamento, heap dump | |
Gráficos, análise de memória e CPU |
| Java Flight Recorder | Análise profunda de eventos da JVM | |
Análise no JMC, “caixa‑preta” |
| JDK Mission Control | Visualização de arquivos JFR | programa separado | Análises detalhadas, relatórios |
Recomendações
- Monitore não só em produção, mas também na fase de testes. Assim você detecta mais cedo vazamentos de memória e threads travadas.
- Heap dump — não dói! Capture um dump de memória se suspeitar de vazamento e estude‑o no VisualVM.
- Não tenha medo de experimentar o JFR. Mesmo que nem tudo fique claro de imediato, os eventos e gráficos ajudam a encontrar gargalos.
- É possível usar o JMX programaticamente. Por exemplo, para enviar métricas ao Prometheus/Grafana.
- Perfilamento não é para uso contínuo. Ative os profiladores de forma pontual; caso contrário, o aplicativo pode ficar mais lento.
6. Erros comuns no monitoramento da JVM
Erro nº 1: não monitorar nada. Muitos iniciantes pensam que, se o aplicativo “está funcionando”, está tudo bem. Na prática, problemas de memória e de threads costumam aparecer sob carga ou com o tempo. Não tenha preguiça de abrir o VisualVM/JConsole ao menos periodicamente.
Erro nº 2: capturar heap dump em aplicativos enormes sem preparação. Um heap dump de um aplicativo grande pode pesar gigabytes e “congelar” o processo por alguns segundos. Faça isso em ambiente de teste ou em horários de menor movimento, no caso de produção.
Erro nº 3: ignorar os indicadores de GC e de threads. Uma fração de tempo constantemente alta no GC é um sinal de alerta! E, se o número de threads cresce de forma estável, investigue vazamento de threads.
Erro nº 4: não analisar os resultados do monitoramento. Apenas abrir o VisualVM é pouco. Veja quais objetos ocupam memória, quais métodos consomem CPU, por que aparecem deadlocks. Analise os stack traces e as causas.
Erro nº 5: usar profiladores em produção sem entender. O perfilamento pode desacelerar significativamente o aplicativo. Ative‑o apenas para diagnóstico, e não o tempo todo.
GO TO FULL VERSION