async-profiler - Profiler de Overhead Baixo para JVM
async-profiler é um profiler de amostragem de overhead baixo para a JVM. Profilers Java tradicionais amostring apenas em safepoints, o que enviesça resultados em relação a tudo que acontece sentir um safepoint e pode esconder o hot path real. async-profiler usa AsyncGetCallTrace mais eventos de perf para amostrar em qualquer lugar, incluindo código nativo e frames de kernel, dando um quadro muito mais honesto. Ele perfila CPU, alocações, contenção de lock, e mais, e exporta flame graphs ou JFR.
Instalação
| Método | Como |
|---|
| Download | Pegar o tarball de release para sua plataforma |
| Extract | tar xzf async-profiler-*.tar.gz |
| Executar | ./bin/asprof <pid> (mais novo) ou ./profiler.sh <pid> |
| Permissões | pode precisar sysctl kernel.perf_event_paranoid=1 e kernel.kptr_restrict=0 |
| Verificar | ./bin/asprof --version |
Profiling Básico
| Comando | Descrição |
|---|
asprof -d 30 -f out.html <pid> | Perfil 30s → flame graph |
asprof -e alloc -d 30 -f alloc.html <pid> | Profiling de alocação |
asprof -e lock -d 30 -f lock.html <pid> | Contenção de lock |
asprof -e wall -d 30 -f wall.html <pid> | Wall-clock (inclui espera) |
asprof start <pid> / asprof stop -f out.html <pid> | Manual start/stop |
jps | Encontrar o pid da JVM |
Tipos de Evento
| Evento | Mede |
|---|
cpu | Tempo de CPU (padrão) |
alloc | Alocações de heap por stack |
lock | Contenção de lock/monitor |
wall | Wall-clock incluindo tempo bloqueado |
itimer | Fallback quando perf não está disponível |
cache-misses, page-faults | Eventos de perf de hardware/software |
# Onde a app realmente gasta wall-clock time (incl. IO waits)?
./bin/asprof -e wall -t -d 30 -f wall.html <pid>
| Flag | Produz |
|---|
-f out.html | Flame graph interativo |
-o collapsed | Stacks dobrados (para ferramentas FlameGraph) |
-o tree | Call tree |
-o flat | Lista flat de hot-method |
-f out.jfr | Gravação JFR (abrir em JMC) |
-t | Dividir por thread |
# Perfil do JVM startup (captura warmup)
java -agentpath:/path/libasyncProfiler.so=start,event=cpu,file=profile.html \
-jar app.jar
| Opção de agent | Propósito |
|---|
start | Começar imediatamente |
event=cpu|alloc|lock | O que amostrar |
file=NAME | Caminho de saída |
interval=10ms | Intervalo de amostragem |
jfr | Emitir formato JFR |
Lendo o Flame Graph
| Característica | Significado |
|---|
| Largura | Compartilhamento de amostras (tempo) — mais largo é mais quente |
| Altura | Profundidade de stack, não custo |
| Cores | Java (verde), nativo (amarelado), kernel (laranja) |
| Click | Zoom em uma subárvore |
| Search | Destacar frames correspondentes |
Procure por plataaus largos — um único frame consumindo um grande compartilhamento horizontal é seu hot spot. Frames mistos Java/nativo/kernel são exatamente o que profilers enviesados por safepoint ocultam.
Workflows Comuns
# 1) Hot spots de CPU em um serviço rodando
./bin/asprof -d 60 -f cpu.html $(jps | grep MyApp | cut -d' ' -f1)
# 2) Perseguindo pressão de GC — quem aloca mais?
./bin/asprof -e alloc -d 60 -f alloc.html <pid>
# 3) Threads parecem ociosas mas latência é alta → wall-clock
./bin/asprof -e wall -t -d 30 -f wall.html <pid>
# 4) Contenção em um recurso compartilhado
./bin/asprof -e lock -d 30 -f lock.html <pid>
async-profiler vs Alternativas
| Aspecto | async-profiler | JFR | VisualVM |
|---|
| Viés de safepoint | Evitado | Reduzido | Presente |
| Frames nativo/kernel | Sim | Limitado | Não |
| Overhead | Muito baixo | Baixo | Maior |
| Profiling de alocação | Sim | Sim | Básico |
| Melhor para | Hot spots precisos de JVM | Gravação contínua integrada | Inspeção GUI rápida |
O contraparte JVM para perf + FlameGraph para código nativo.
Recursos