Perfilando código Java: encontrando gargalos na prática

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Perfilando código Java: encontrando gargalos na prática



Todo desenvolvedor Java, mais cedo ou mais tarde, enfrenta problemas de desempenho: a aplicação roda lentamente, consome muita memória ou "congela" inesperadamente. Nessas situações, o perfilamento é indispensável. Neste artigo, vamos explorar como encontrar gargalos no código Java na prática, usando ferramentas modernas de perfilamento.



O que é perfilamento e por que ele é necessário?



Perfilamento (profiling) é uma análise dinâmica do programa que coleta dados sobre seu funcionamento: uso de CPU, consumo de memória, tempo de execução de métodos, quantidade de objetos criados e threads. Diferente da registro de logs, o perfilamento fornece uma imagem precisa dos "gargalos" sem a necessidade de ajustar temporizadores manualmente.



Principais tipos de perfilamento:

  • Perfilamento de CPU — determina quais métodos consomem mais tempo de processador.
  • Perfilamento de memória — identifica vazamentos de memória, frequência de criação de objetos e funcionamento do coletor de lixo (GC).
  • Perfilamento de threads — analisa bloqueios, deadlocks e estado das threads.


Ferramentas para perfilamento Java



Vamos analisar três ferramentas populares que ajudarão você a encontrar gargalos.



1. VisualVM

Ferramenta gratuita incluída no JDK. Ideal para análise rápida de uma aplicação em execução. Permite monitorar CPU, memória, threads e até realizar dumps de heap.

// Iniciar VisualVM pela linha de comandojvisualvm.exe


2. JProfiler

Profiler comercial com um conjunto poderoso de recursos: análise detalhada de CPU, memória, JDBC, JPA e consultas SQL. Ideal para aplicações enterprise.



3. Java Flight Recorder (JFR) + JDK Mission Control

Ferramenta integrada à JVM (disponível desde o Java 11). Coleta eventos de baixo nível sem impacto significativo no desempenho. Recomendado para ambientes de produção.

// Gravação JFR por 60 segundosjcmd <PID> JFR.start duration=60s filename=recording.jfr


Exemplo prático: encontrando um gargalo



Suponha que temos uma aplicação que processa uma lista de usuários e gera relatórios. Ela está lenta. Vamos escrever um código de teste simples e perfilá-lo com o VisualVM.



Passo 1. Preparação do código

import java.util.ArrayList;import java.util.List;

public class SlowApp { public static void main(String[] args) { List<String> users = new ArrayList<>(); for (int i = 0; i < 100000; i++) { users.add("User" + i); } processUsers(users); }

public static void processUsers(List<String> users) { for (String user : users) { String report = generateReport(user); // Simulação de salvamento System.out.println(report.length()); } }

public static String generateReport(String user) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < 1000; i++) { sb.append(user).append(" - data ").append(i).append(""); } return sb.toString(); }}


Passo 2. Iniciar o perfilamento

Execute a aplicação e abra o VisualVM. Selecione o processo no painel esquerdo, vá para a aba "Profiler" e clique em "CPU" para iniciar o perfilamento.



Passo 3. Análise dos resultados

Após parar o perfilamento, você verá uma tabela com os métodos ordenados pelo tempo gasto. No nosso exemplo, o método generateReport estará no topo — ele consome mais de 90% do tempo de CPU devido à concatenação de strings no loop.



Passo 4. Otimização

Vamos substituir o StringBuilder por um buffer pré-alocado:


                
                

Blogs

Book Recommendations