From Bytecode to Native Code in HotSpot JVM
summary
Explains how HotSpot moves Java bytecode through interpreter → C1 → C2 with client threshold ~1.5k invocations, tiered compilation to C2 for heavy methods, shows that JIT inlining removes direct vs getter/setter penalty (native-compiled runs converge around ~64–68 ns per iteration while interpreted run is much slower), demonstrates monomorphic → bimorphic → megamorphic behavior (single-impl runs ~5 ns, three-impls stop inlining and stabilize ~8–9 ns), and uses hsdis + -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly and JITWatch to inspect generated assembly.
AI-written summary · about
chapters (20)
- 0:00Introduction to HotSpot JVM
- 1:46What is the JVM
- 3:10Java C and bytecode basics
- 5:21Class file format
- 7:32Bytecode instruction families
- 10:14Stack frames and local variables
- 13:08Runtime constant pool
- 16:01Exception handling at bytecode level
- 18:29Quiz on bytecode ambiguities
- 22:47Default methods and lambdas in interfaces
- 25:39HotSpot execution engine
- 29:10Just-In-Time compilation process
- 32:06Dynamic optimizations in JIT
- 34:24Intrinsics and method inlining
- 35:50JVM arguments for JIT control
- 36:37Viewing native code from bytecode
- 37:20Demo: Direct vs getter/setter access
- 41:24Demo: Virtual method call types
- 47:29JIT Watch tool overview
- 48:54Microbenchmarking advice
related talks
49mAn Introduction to JVM Performance
01h 01mAn Introduction to JVM Performance
59mAn Introduction to JVM Performance
41mAn Introduction to JVM Performance
01h 07mFrom Java to Assembly: Down the Rabbit Hole
46mJIT Compiler From the Ground Up
54mJava performance techniques The cost of HotSpot runtime optimizations
44mJIT Me Baby One More Time
