async-profiler - Perfilador JVM de Bajo Overhead Hoja de Trucos
async-profiler es un perfilador de muestreo de bajo overhead para la JVM. Los perfiladores Java tradicionales muestrean solo en safepoints, lo que sesga resultados hacia cualquier código que suceda estar cerca de un safepoint y puede ocultar el camino caliente real. async-profiler usa AsyncGetCallTrace más eventos perf para muestrear en cualquier lugar, incluyendo código nativo y frames de kernel, dando una imagen mucho más honesta. Perfila CPU, asignaciones, contención de bloqueos y más, y exporta flame graphs o JFR.
Instalación
| Método | Cómo |
|---|
| Descargar | Obtener el tarball de release para tu plataforma |
| Extraer | tar xzf async-profiler-*.tar.gz |
| Ejecutar | ./bin/asprof <pid> (más nuevo) o ./profiler.sh <pid> |
| Permisos | puede necesitar sysctl kernel.perf_event_paranoid=1 y kernel.kptr_restrict=0 |
| Verificar | ./bin/asprof --version |
Perfilado Básico
| Comando | Descripción |
|---|
asprof -d 30 -f out.html <pid> | Perfilar 30s → flame graph |
asprof -e alloc -d 30 -f alloc.html <pid> | Perfilado de asignación |
asprof -e lock -d 30 -f lock.html <pid> | Contención de bloqueo |
asprof -e wall -d 30 -f wall.html <pid> | Wall-clock (incluye espera) |
asprof start <pid> / asprof stop -f out.html <pid> | Inicio/parada manual |
jps | Encontrar el pid de JVM |
Tipos de Evento
| Evento | Mide |
|---|
cpu | Tiempo de CPU (predeterminado) |
alloc | Asignaciones de heap por stack |
lock | Contención de lock/monitor |
wall | Wall-clock incluyendo tiempo bloqueado |
itimer | Fallback cuando perf no disponible |
cache-misses, page-faults | Eventos perf de hardware/software |
# ¿Dónde está la app realmente gastando tiempo de wall-clock (incl. waits de IO)?
./bin/asprof -e wall -t -d 30 -f wall.html <pid>
| Flag | Produce |
|---|
-f out.html | Flame graph interactivo |
-o collapsed | Stacks plegados (para herramientas FlameGraph) |
-o tree | Árbol de llamadas |
-o flat | Lista plana de métodos calientes |
-f out.jfr | Grabación JFR (abrir en JMC) |
-t | Dividir por thread |
Lanzar con el Agente
# Perfilar desde el inicio de JVM (captura warmup)
java -agentpath:/path/libasyncProfiler.so=start,event=cpu,file=profile.html \
-jar app.jar
| Opción del agente | Propósito |
|---|
start | Comenzar inmediatamente |
event=cpu|alloc|lock | Qué muestrear |
file=NAME | Ruta de salida |
interval=10ms | Intervalo de muestreo |
jfr | Emitir formato JFR |
Leyendo el Flame Graph
| Característica | Significado |
|---|
| Ancho | Proporción de muestras (tiempo) — más ancho es más caliente |
| Alto | Profundidad de stack, no costo |
| Colores | Java (verde), nativo (amarillento), kernel (naranja) |
| Click | Zoom en un subárbol |
| Búsqueda | Destacar frames coincidentes |
Busca mesetas anchas — un único frame consumiendo una gran parte horizontal es tu punto caliente. Frames mixtos Java/nativo/kernel son exactamente lo que perfiladores sesgados por safepoint ocultan.
Flujos de Trabajo Comunes
# 1) Puntos calientes de CPU en un servicio ejecutándose
./bin/asprof -d 60 -f cpu.html $(jps | grep MyApp | cut -d' ' -f1)
# 2) Persiguiendo presión de GC — ¿quién asigna más?
./bin/asprof -e alloc -d 60 -f alloc.html <pid>
# 3) Threads se ven inactivos pero la latencia es alta → wall-clock
./bin/asprof -e wall -t -d 30 -f wall.html <pid>
# 4) Contención en un recurso compartido
./bin/asprof -e lock -d 30 -f lock.html <pid>
async-profiler vs Alternativas
| Aspecto | async-profiler | JFR | VisualVM |
|---|
| Sesgo de safepoint | Evitado | Reducido | Presente |
| Frames de nativo/kernel | Sí | Limitado | No |
| Overhead | Muy bajo | Bajo | Mayor |
| Perfilado de asignación | Sí | Sí | Básico |
| Mejor para | Puntos calientes JVM precisos | Grabación continua integrada | Inspección GUI rápida |
La contrapartida de JVM a perf + FlameGraph para código nativo.
Recursos