Careeroza
JIT Compilation
Interpreter + JIT
javac produces bytecode. The JVM first interprets it. Methods that run often ("hot") are compiled to native machine code by the JIT (Just-In-Time) compiler. HotSpot uses tiered compilation:
level 0 interpreter ── counts calls and loop iterations
level 3 C1 compiler (quick) ── compiled fast, with profiling
level 4 C2 compiler (optimized)── uses the profile: inlining, escape analysis,
loop unrolling, dead-code removal
deoptimize ◄────────── if an assumption breaks (new subclass loaded...)Key Optimizations
| Optimization | What it does |
|---|---|
| Inlining | copies small hot methods (getters) into the caller: no call overhead |
| Escape analysis | an object that never leaves a method may be allocated on the stack or removed entirely |
| Loop unrolling / vectorization | fewer jumps, SIMD instructions |
| Devirtualization | turns an interface call with one implementation into a direct call |
| Lock elision | removes locks on objects no other thread can see |
Warm-up
Because of JIT, Java apps get faster after running a while (warm-up). That is why micro-benchmarks with System.nanoTime() often lie — use JMH. For fast startup (serverless, CLIs) look at GraalVM native image, CDS (class data sharing) and CRaC.
Example
See which methods get compiled:
java -XX:+PrintCompilation MainExample output
45 1 3 java.lang.String::hashCode (60 bytes)
52 7 4 java.lang.String::charAt (25 bytes)
118 41 % 4 Main::sumLoop @ 4 (27 bytes)
120 42 4 Main::sumLoop (27 bytes)