JVM tool guide · profiling

async-profiler: Sampled CPU, Allocations and Flame Graphs

async-profiler is the de-facto standard sampling profiler for the JVM. Unlike instrumenting profilers, it uses AsyncGetCallTrace and perf-event sampling to record stack traces without stopping the world, so overhead stays low even on hot production paths. It also produces the flame graphs famously used for CPU and allocation visualization.

You can run it as a standalone agent (async-profiler -p ...), or use it inside flight-recorder integration and IntelliJ IDEA's bundled profiler, which wraps it.

Official async-profiler project

Use it when

• You need to find which methods actually consume CPU in a production-like workload.

• You want to see allocation sites and native stack frames (like JIT/GC related?) — async-profiler is one of the few profilers that captures native stacks cleanly.

• You want flame graphs without a commercial license or an instrumentation-based profiler.

Skip it when

• You need always-on continuous recording (prefer JFR, which is bundled and designed for that).

• You only need heap-leak 'dominators' (Eclipse MAT is the tool).

Download and check the agent

The project ships prebuilt agents for common platforms. Managed profilers (IntelliJ, JMC) bundle an async-profiler agent for you.

# Download release from GitHub releases (async-profiler-x.y-linux-x64.tar.gz)
tar xzf async-profiler*.tar.gz
./profiler.sh -v

Profile CPU for a fixed duration

Record 30 seconds of CPU samples, then collect the flame graph HTML. -d is duration, -f is output file, -e cpu selects the event.

# Profile the JVM with PID <pid> for 30s
./profiler.sh -d 30 -f /tmp/flame.html -e cpu <pid>

# Open /tmp/flame.html in a browser

Allocation profiling

Switch the event to alloc to show allocation counts and sizes per call path (uses -Xint sampling by allocation).

./profiler.sh -d 30 -f /tmp/alloc.html -e alloc <pid>

Emit JFR-compatible output

Generate a .jfr file you can open in JDK Mission Control as an alternative to the HTML flame graph.

./profiler.sh -d 30 -o jfr -f /tmp/cpu.jfr <pid>

Use it inside IntelliJ IDEA

IntelliJ's Run > 'Profile

' uses async-profiler under the hood and opens flame graphs in the IDE. This is the lowest-friction path for most developers.

Quick start

Get productive in minutes

First CPU flame graph in one command

Point it at a running JVM and open the result.

# In the async-profiler directory
./profiler.sh -d 30 -f ~/flame.html -e cpu <pid>
open ~/flame.html

Frequently asked questions

Where is async-profiler bundled so I don't download it?

IntelliJ IDEA's built-in profiler, JetBrains Runtime tools, and several APM products package async-profiler. If you manage a plain JDK, download the release tarball or use your package manager (many distros ship 'async-profiler').

CPU vs allocation profiling — when?

CPU profiling answers 'where does the time go' for hot loops and steady-state workloads. Allocation profiling answers 'where do objects come from' and is the first stop for GC-pressure/leak suspects.

Does async-profiler work on containerized/k8s JVMs?

Yes — attach by PID works as long as you run it in the same container/namespace as the JVM (or the host can reach /proc/). On cgroup-limited environments, ensure /proc and perf permissions are available.

Last updated August 2026 · JVM Tools is independent and not affiliated with Oracle.