JIT compilation and warm-up

JVM · lesson 12 of 34 · 4 min read

Code starts interpreted, gets compiled once it is proven hot, and only then runs at full speed.

Open this lesson in the learning hub

Key points

  • Every method starts interpreted. Compiling everything up front would waste time on code that only runs twice.
  • The JVM counts method invocations and loop back-edges. Cross a threshold and that method is queued for compilation.
  • Compilation is tiered: C1 compiles quickly and adds profiling counters, then C2 uses that profile to compile really well.
  • The profile lets the JIT bet - this call is always the same type, this branch never happens - and emit code for the common case.
  • When a bet turns out wrong the JVM deoptimises: back to the interpreter, then recompile with better information.
  • This is warm-up. Benchmark a cold JVM and you are mostly measuring the interpreter, not your code.

Example

public class Main {

    static long mix(long h, int i) { return 31 * h + (i ^ (h >>> 7)); }

    static long round(int n) {
        long h = 1125899906842597L;
        for (int i = 0; i < n; i++) { h = mix(h, i); }
        return h;
    }

    public static void main(String[] args) {
        long guard = 0;
        System.out.println("round   microseconds for the same 20,000 calls");
        for (int r = 1; r <= 40; r++) {
            long t0 = System.nanoTime();
            guard += round(20_000);
            long us = (System.nanoTime() - t0) / 1000;
            if (r <= 4 || r == 10 || r == 20 || r == 40) {
                System.out.printf("%5d   %8d%n", r, us);
            }
        }
        System.out.println("checksum " + guard);
        System.out.println();
        System.out.println("Round 1 is interpreted bytecode. C1 compiles it fast and rough,");
        System.out.println("then C2 recompiles the hot path into genuinely good machine code.");
        System.out.println("That is why a fresh JVM is slow for its first few thousand requests.");
    }
}

The first thousand calls are not the ones worth timing.

This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the JVM course, and every lesson in it is listed on the JVM contents page.