Interview Prep Zoneby CuriouserLabs

Question 5 of 5 · staff level

What does the JIT compiler do, and why do Java services need warm-up? What are your options to reduce it?

🎤 Say this first

The JVM starts by interpreting bytecode, profiles hot paths, then compiles them with C1 (fast, light optimization) and later C2 (slow, aggressive) — tiered compilation. Optimizations like inlining, escape analysis and devirtualization rely on runtime profile data, which is why peak throughput arrives minutes after boot. To cut warm-up: CDS/AppCDS, AOT cache (Project Leyden, JDK 24+), CRaC checkpoint/restore, or GraalVM native image — each trading peak performance or operational complexity for startup.

The full picture

  • Tiered pipeline: interpreter → C1 with profiling → C2 (or Graal). Hot methods get recompiled; cold code may never be compiled at all.
  • Speculative optimization: C2 inlines the observed implementation of a virtual call (monomorphic dispatch). If a new class shows up later, the JVM deoptimizes back to the interpreter and recompiles — correctness is preserved via 'uncommon traps'.
  • Why benchmarks lie: dead-code elimination and on-stack replacement wreck naive System.nanoTime() loops — use JMH, which handles warm-up, forks and blackholes.
Startup optionWhat it doesCost
CDS / AppCDSPre-parsed class metadata shared across JVMsNearly free — enable it
AOT cache (Leyden)Reuses training-run compilation stateRequires representative training run
CRaCSnapshot a warmed JVM, restore in msFramework + resource-lifecycle support needed
GraalVM native imageFull AOT, ms startup, low RSSClosed-world: reflection config, no C2 peak, longer builds

🔄 Likely follow-up questions

  • What is on-stack replacement (OSR)?
  • Why can a final field or a sealed hierarchy help the JIT?
  • When would you choose native image for a Spring Boot service, and what breaks?