HotSpot Tiered Compilation

HotSpot tiered compilation uses multiple JIT compiler levels to balance startup speed with the quality of optimized machine code. Code can begin with relatively quick compilation and later be recompiled with stronger optimizations when runtime profiling shows it is worthwhile.

The HotSpot JVM can compile frequently executed Java bytecode into native machine code at runtime. Tiered compilation combines different compiler strategies so the JVM does not have to choose between very fast compilation and maximum optimization from the beginning.

The commonly discussed tiers range from interpretation through progressively more optimized compiled code. In a typical tiered setup, C1 (client) compilation produces native code relatively quickly, while C2 (server) compilation spends more time optimizing code that has demonstrated sustained execution. Runtime profiling helps HotSpot decide which methods or loops deserve additional compilation effort.

A method can therefore move through compilation levels during its lifetime. Early execution gathers profiling information, faster compilation can reduce the cost of waiting for optimized code, and later compilation can exploit accumulated information such as call frequencies and type behavior. This approach is especially useful for long-running server applications.

Tiered compilation is a runtime strategy rather than a change to Java source semantics. The generated machine code is an implementation detail of the JVM, so application behavior should remain governed by the Java language and platform specifications, although performance can vary substantially depending on compilation decisions and runtime workload.

Key points

Interview questions

What are C1 and C2 in HotSpot?

C1 and C2 are HotSpot JIT compiler components associated with different optimization strategies. C1 generally compiles quickly and is useful when code needs native execution without a large compilation delay. C2 generally performs more aggressive optimization and benefits from richer profiling information. Tiered compilation allows the JVM to combine these strengths.

Why does HotSpot use tiered compilation?

It is a trade-off between compilation cost and the quality of generated machine code. A highly optimizing compiler can take significant CPU time, which is undesirable for code that runs only briefly. Faster compilation can provide useful native code earlier. HotSpot can then spend more effort on code that profiling shows is important.

How does profiling influence tiered compilation?

HotSpot observes runtime behavior such as execution frequency and other profile information while the application runs. That information helps identify code where additional compilation effort is likely to pay off. A method can first receive faster compiled code and later be compiled again using stronger optimization informed by the collected profile. The exact decisions are implementation details of the JVM.

How is JIT compilation different from Java compilation with javac?

`javac` normally runs before the application and transforms Java source into JVM bytecode. JIT compilation happens while the application is running and transforms selected bytecode into native machine code. The JIT can use information about the actual workload that was unavailable during ordinary source compilation. This enables runtime-specific optimization.

What is a practical benefit of tiered compilation for a backend service?

A backend service often has a mix of short-lived paths and long-running hot paths. Tiered compilation can avoid spending expensive optimization time on code that rarely executes while still optimizing heavily used request-processing code. As the service warms up, profiling can improve the quality of compilation decisions. This can help balance startup behavior and steady-state throughput.