Skip to content

Guide

What is the difference between the interpreter and the JIT compiler?

How HotSpot runs bytecode: the interpreter executes it first, profiling finds hot methods, and the C1 and C2 JIT compilers turn them into machine code, with real PrintCompilation output.

Interpreter

JVM specification

Executes bytecode instruction by instruction; in HotSpot each bytecode is a pre-generated machine-code template.

Simply put

The interpreter reads one bytecode instruction, does what it says, then moves to the next. It can start immediately, without waiting for any compilation.

What a developer sees

Every Java program starts out interpreted. HotSpot’s is a template interpreter: at start-up it generates a small piece of machine code for each bytecode, then runs a method by jumping from template to template.

Code that runs once or rarely, such as start-up, configuration and error handling, may never leave the interpreter. -Xint makes HotSpot interpret everything, which makes long-running programs dramatically slower and shows how much the JIT compiler does.

Picture it

An interpreter at a meeting, translating each sentence as soon as it is spoken.

Each sentence

Each bytecode instruction

Translating as it goes

Executing one instruction at a time, with no preparation

The listener

The processor (CPU)

Where the picture stops working

HotSpot’s interpreter does not work anything out afresh: it runs a ready-made machine-code template for each kind of instruction. It also keeps counts and profiles while it runs, which the JIT compiler uses later.

Deep dive: the specification and HotSpot in detail

JVMS §2.11 describes the conceptual loop: fetch an opcode, fetch its operands, execute the action, repeat. HotSpot's template interpreter is not a switch loop in C++: at VM start-up it generates a small machine-code template for every bytecode (TemplateTable) and dispatches from one to the next through a table indexed by opcode. It keeps the bytecode pointer, locals pointer and top-of-stack value in registers, increments invocation and back-edge counters, records profiles, and polls for safepoints at returns and loop back-edges. The generated interpreter lives in the code cache.

The specification requires

Conceptual fetch-decode-execute loop over JVM instructions.

HotSpot (JDK 25) does

HotSpot: template interpreter generated at start-up, with register-cached state and profiling.

Common misconceptions

  • The interpreter parses Java source or text.

    It executes bytecode from class files. Source code never reaches the JVM.

  • HotSpot interprets with a big `switch` statement.

    Standard builds use generated machine-code templates. The C++ BytecodeInterpreter exists only for the Zero port, which has no JIT.

Sources

JIT compiler

HotSpot · JDK 25

Compiles hot methods to native machine code while the program runs, guided by profiles.

Simply put

The just-in-time compiler watches for code that runs a lot and translates it into native machine code for your CPU while the program is running. From then on, that code runs much faster than in the interpreter.

What a developer sees

HotSpot counts how often each method runs. Hot methods are compiled to machine code while your program keeps running: first by C1 (tier 3, quick, with profiling), then by C2 (tier 4, heavily optimized). -XX:+PrintCompilation prints each compilation.

Because of this warm-up, the first seconds of a program run slower. Benchmark with a harness such as JMH rather than with a single timed loop.

Picture it

A musician who notices which pieces are requested every night and learns those by heart, instead of reading them from the sheet music each time.

The sheet music

Bytecode

Reading from the sheet

Interpreting

Learning a piece by heart

Compiling a method to machine code

Requested every night

Hot code, found by counting calls and loops

Where the picture stops working

The JIT can also unlearn: if an assumption behind compiled code stops being true (for example, a new subclass is loaded), the code is thrown away and the method runs in the interpreter until it is compiled again. And it practises in the background while the program keeps running.

Deep dive: the specification and HotSpot in detail

HotSpot uses tiered compilation (compilationPolicy.hpp): level 0 interpreter; 1 C1 without profiling; 2 C1 with invocation and back-edge counters; 3 C1 with full profiling; 4 C2. The common path is 0 → 3 → 4; trivial methods go to level 1; when the C2 queue is long, methods may take 0 → 2 → 3 → 4. Transitions are governed by thresholds such as Tier3InvocationThreshold (200) and Tier4InvocationThreshold (5000), scaled by compiler-queue load. Compilation runs in background compiler threads (3 in our measured run on 4 CPUs) while the application keeps executing.

OpenJDK 25 builds ship C1 and C2; GraalVM distributions can plug in the Graal compiler instead through JVMCI.

Watching tiers with -XX:+PrintCompilationShell
$ java -XX:+PrintCompilation -cp . Hot | grep Hot::

Verified with OpenJDK 25.0.4 · Linux x64; columns: time (ms), compile id, flags (% = OSR), tier, method

Common misconceptions

  • The JIT compiles the whole program at start-up.

    It compiles individual methods (and loops, via OSR) once they are hot. Most code is never compiled.

  • All JVMs use C1 and C2.

    C1/C2 and tiered compilation are HotSpot design choices. Other JVMs use different compilers, and some run ahead-of-time compiled code.

Sources

Tiers and deoptimization

Tiered compilation

HotSpot's step-by-step approach: interpret first, then compile quickly, then compile thoroughly.

Five levels: 0 interpreter, 1 C1 without profiling, 2 C1 with counters, 3 C1 with full profiling, 4 C2. The usual path is 0 → 3 → 4, governed by thresholds such as Tier3InvocationThreshold (200) and Tier4InvocationThreshold (5000).

Tiered compilation in the glossary
Deoptimization

Falling back from optimized code to the interpreter when an assumption turns out wrong.

HotSpot reconstructs interpreter frames from compiled code's debug information when an is hit or a dependency is invalidated, then continues in the interpreter; the method may be recompiled later.

Deoptimization in the glossary
JVM Atlas

Explore the machine behind Java programs. A free, open-source atlas of the Java Virtual Machine. Specification baseline: Java SE 25. Implementation details: OpenJDK HotSpot, JDK 25.

MIT licensed · no accounts, no tracking, no backend · your progress stays in your browser.

JVM Atlas is an independent educational project and is not affiliated with or endorsed by Oracle. Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.