Skip to content

async-profiler - Low-Overhead JVM Profiler Cheatsheet

async-profiler - Low-Overhead JVM Profiler Cheatsheet

async-profiler is a low-overhead sampling profiler for the JVM. Traditional Java profilers sample only at safepoints, which biases results toward whatever code happens to sit near a safepoint and can hide the real hot path. async-profiler uses AsyncGetCallTrace plus perf events to sample anywhere, including native code and kernel frames, giving a far more honest picture. It profiles CPU, allocations, lock contention, and more, and exports flame graphs or JFR.

Installation

MethodHow
DownloadGet the release tarball for your platform
Extracttar xzf async-profiler-*.tar.gz
Run./bin/asprof <pid> (newer) or ./profiler.sh <pid>
Permissionsmay need sysctl kernel.perf_event_paranoid=1 and kernel.kptr_restrict=0
Verify./bin/asprof --version

Basic Profiling

CommandDescription
asprof -d 30 -f out.html <pid>Profile 30s → flame graph
asprof -e alloc -d 30 -f alloc.html <pid>Allocation profiling
asprof -e lock -d 30 -f lock.html <pid>Lock contention
asprof -e wall -d 30 -f wall.html <pid>Wall-clock (includes waiting)
asprof start <pid> / asprof stop -f out.html <pid>Manual start/stop
jpsFind the JVM pid

Event Types

EventMeasures
cpuCPU time (default)
allocHeap allocations by stack
lockLock/monitor contention
wallWall-clock including blocked time
itimerFallback when perf is unavailable
cache-misses, page-faultsHardware/software perf events
# Where is the app actually spending wall-clock time (incl. IO waits)?
./bin/asprof -e wall -t -d 30 -f wall.html <pid>

Output Formats

FlagProduces
-f out.htmlInteractive flame graph
-o collapsedFolded stacks (for FlameGraph tooling)
-o treeCall tree
-o flatFlat hot-method list
-f out.jfrJFR recording (open in JMC)
-tSplit by thread

Launching With the Agent

# Profile from JVM startup (captures warmup)
java -agentpath:/path/libasyncProfiler.so=start,event=cpu,file=profile.html \
  -jar app.jar
Agent optionPurpose
startBegin immediately
event=cpu|alloc|lockWhat to sample
file=NAMEOutput path
interval=10msSampling interval
jfrEmit JFR format

Reading the Flame Graph

FeatureMeaning
WidthShare of samples (time) — wider is hotter
HeightStack depth, not cost
ColorsJava (green), native (yellow-ish), kernel (orange)
ClickZoom into a subtree
SearchHighlight matching frames

Look for wide plateaus — a single frame consuming a large horizontal share is your hot spot. Mixed Java/native/kernel frames are exactly what safepoint-biased profilers hide.

Common Workflows

# 1) CPU hotspots in a running service
./bin/asprof -d 60 -f cpu.html $(jps | grep MyApp | cut -d' ' -f1)

# 2) Chasing GC pressure — who allocates most?
./bin/asprof -e alloc -d 60 -f alloc.html <pid>

# 3) Threads look idle but latency is high → wall-clock
./bin/asprof -e wall -t -d 30 -f wall.html <pid>

# 4) Contention on a shared resource
./bin/asprof -e lock -d 30 -f lock.html <pid>

async-profiler vs Alternatives

Aspectasync-profilerJFRVisualVM
Safepoint biasAvoidedReducedPresent
Native/kernel framesYesLimitedNo
OverheadVery lowLowHigher
Allocation profilingYesYesBasic
Best forAccurate JVM hotspotsBuilt-in continuous recordingQuick GUI inspection

The JVM counterpart to perf + FlameGraph for native code.

Resources