Profiling and flame graphs

A profile shows where a running JVM spends its time, memory or lock waits, as a flame graph.

A flame graph of a JVM's CPU use, with the methods that use the most

Starting a profile

Connect to a JVM (see JVM connections) and click Profile… in its Threads tab, or Profile in the bar above its log. Then:

  1. Measure: what to look at (below).
  2. for … seconds (default 30).
  3. with: the engine, async-profiler or Flight Recorder.
  4. Per thread: one flame graph per thread, each thread’s name on top.
  5. Start Profiling. The JVM keeps running as usual. Stop ends a run early.

The gray line under the controls says what the mode shows and, in orange, what it costs the JVM.

Measure Shows Engines
CPU Where the threads use the CPU both
Wall clock Where the threads spend their time, running or waiting both
Allocations Where memory is allocated, and for what both
Live objects (memory leaks) Objects allocated during the run and still alive at its end: what makes the heap grow. Run it while memory use climbs async-profiler
Locks Where threads wait to get locks both
Native memory Where native memory (malloc, direct buffers) is allocated async-profiler
Native memory leaks Native memory allocated during the run and never freed (the last tenth of the run is left out: it may simply not be freed yet) async-profiler
Native locks Where threads wait for native (pthread) locks async-profiler
Calls of a method Every call of a method you name (com.acme.Api.handle, java.io.FileInputStream.read*), and where it comes from async-profiler
Slow calls of a method Calls slower than a time you give (default 50 ms), with their total time async-profiler
Hardware event Cache misses, page faults, context switches and the like (Linux) async-profiler
Everything at once CPU, wall clock, allocations, live objects, locks and native memory from one run both (Flight Recorder: its own kinds)

For a method, name one class: a * is allowed only in the method name (com.acme.orders.Api.*), since tracing the methods of many classes can make the JVM stop answering.

The two engines

What it costs

See also What each action costs a running service.

Reading a flame graph

Hover a frame for its name, its share with what it calls, its share on its own, and what kind of code it is.

Frame colours

The colour says what kind of code a frame is. Neighbouring frames vary a little in shade so they are easy to tell apart.

Colour Light Dark Kind
green Java code (your code and libraries)
pale green The JDK’s own Java code (java., javax., jdk., sun., com.sun.)
teal Inlined Java code, and the class an allocation or lock was for
yellow Native code (C, C++, the JVM itself)
orange The operating system’s kernel
gray all, and thread names with Per thread
pink Frames that match highlight methods

Frames above the one you zoomed into are faded.

Looking closer

Which view

A run that measured several things (Everything at once, or a .jfr file) has a view list to pick CPU, Wall clock, Allocations, Locks and so on. Each run stays in the tab: pick an earlier one in the run list (Run 2 · CPU · 18:07:49).

Comparing runs

Compare with picks an earlier run of the same kind. Each frame is then coloured by how its share (with what it calls) changed:

Two CPU profiles compared: frames that grew in red, shrank in blue

Colour Light Dark Means
red Grew. Full red at 5 percentage points or more, or new since the other run
blue Shrank. Full blue at 5 points or more
gray Changed less than 0.2 points

Between 0.2 and 5 points the colour is in between: the stronger the colour, the bigger the change. The method list gets a Change column: how the method’s own share changed, in points.

What to do: after a change that made things slower, profile before and after under the same load, and look for the reddest wide frames.

Saving and opening profiles

Messages you may see