JAVA HOTSPOT INTERNALS — FULL
NOTES
HotSpot is the default JVM used by Oracle/OpenJDK, designed to deliver high performance
using advanced JIT (Just-in-Time) compilation, adaptive optimization, and efficient memory
management.
1. High-Level Architecture of HotSpot
+-------------------------------+
| Java Application |
+-------------------------------+
|
+--------------------------------+
| Java Runtime (JRE) |
+--------------------------------+
|
+-------------------+-------------------------------+
| | |
+-------------+ +-------------------+ +----------------------------+
| ClassLoader | | Execution Engine | | Memory Management (GC) |
+-------------+ +-------------------+ +----------------------------+
|
+----------------+------------------------+
| Interpreter (Bytecode) |
| +--------------------------------+ |
| | JIT Compilers | |
| | C1 (Client) & C2 (Server) | |
| +--------------------------------+ |
+----------------------------------------+
2. HotSpot Memory Layout
HotSpot divides memory into:
+--------------------------------------+
| Method Area / Metaspace |
+--------------------------------------+
| Heap (Young + Old) |
+--------------------------------------+
| Stack (per thread) |
+--------------------------------------+
| PC Registers |
+--------------------------------------+
| Native Method Area |
+--------------------------------------+
(A) Method Area (since Java 8 → Metaspace)
Stores class-level data:
Class metadata
Constant pool
Field/method descriptions
JIT compiled code
Static variables
In Java 8+ Metaspace:
Uses native memory
Automatically expands (limited by OS memory)
(B) Heap Region
Divided into:
1. Young Generation
Eden
Survivor S0
Survivor S1
Contains newly created objects.
Garbage collection → Minor GC (fast, copy-based).
2. Old Generation
Contains long-living objects.
GC → Major GC / Full GC.
(C) JVM Stacks (one per thread)
Stores:
Local variables
Call frames
Operand stack
Overflow → StackOverflowError
(D) PC (Program Counter) Register
Stores address of current instruction per thread.
(E) Native Method Stack
Used for JNI method calls.
3. Execution Engine Internals
The Execution Engine has:
1. Interpreter
Executes bytecode instruction-by-instruction
Used for cold code
Initial startup is fast
2. JIT Compilers
HotSpot has two JIT compilers:
Compiler Type Purpose
C1 (Client Compiler) Fast, low optimization For quick startup, GUIs, mobile
C2 (Server Compiler) Slow, aggressive optimization For long-running apps (servers)
JVM uses Tiered Compilation → combination of C1 + C2.
4. How HotSpot Executes Code (Adaptive
Optimization)
Bytecode
↓
Interpreter executes it
↓
HotSpot profiling finds hotspots (hot loops/methods)
↓
C1 compiles quickly (simple optimizations)
↓
If still hot, C2 recompiles (deep optimizations)
↓
Replace interpreted code with machine code
↓
Run optimized native code
5. Profiling in HotSpot
HotSpot collects runtime statistics:
Method invocation count
Branch probabilities
Hot loops
Escape analysis data
Type profiles
Inline heuristics
Used for adaptive optimization.
6. Key JIT Optimizations in HotSpot
✔ Method Inlining
Removes method call overhead.
✔ Escape Analysis
Determines if object escapes method:
If not → allocate on stack → eliminate synchronization.
✔ Loop Optimizations
Loop unrolling
Loop invariant code motion
Vectorization
✔ Dead Code Elimination
✔ Constant Propagation
✔ Speculative Optimization + Deoptimization
Assume commonly observed types → optimize → if assumption fails, revert to interpreter.
This is a unique feature of HotSpot.
7. Class Loading in HotSpot
Three Phases:
1. Loading
Bytecode read from .class file
Platform-independent format
2. Linking
Verify (bytecode verification)
Prepare (allocate static memory)
Resolve (convert symbolic to direct references)
3. Initialization
Run static initializers (<clinit>)
8. ClassLoader Hierarchy
Bootstrap ClassLoader
↓
Extension ClassLoader
↓
Application (System) ClassLoader
↓
Custom User ClassLoaders
Uses parent delegation model.
9. Garbage Collectors in HotSpot
HotSpot supports multiple GC algorithms:
1. Serial GC
Simple, single-threaded; good for small apps.
2. Parallel GC
Multi-threaded minor & major GC; best for throughput.
3. CMS (Concurrent Mark Sweep)
Deprecated; low pause GC.
4. G1 GC (Garbage First)
Default after Java 9.
Region-based
Predictable pauses
Designed for big heaps
5. ZGC (Z Garbage Collector)
Ultra-low pause (< 10 ms), massive heaps (TBs).
6. Shenandoah GC
Low-pause GC from RedHat similar to ZGC.
10. HotSpot Compiler Pipeline Diagram
Bytecode
↓
Interpreter
↓ (hot code detected)
C1 Lightweight JIT Compile
↓ (hot enough)
C2 Optimizing JIT Compile
↓
Optimized Native Code
(stored in CodeCache)
11. Code Cache
JIT compiled code, stubs, inline caches stored here.
Divided into:
Non-Profiled Code → C1
Profiled Code → C1 with profiling
C2 Code → Optimized code
Non-Java code (stubs)
12. Inline Caches (PIC/Megamorphic IC)
Used for dynamic dispatch:
Monomorphic → one type
Polymorphic → few types
Megamorphic → many types (fallback to interpreter)
Helps performance of virtual calls.
13. Safepoints
JVM stops threads at safepoints for:
GC
Deoptimization
Class redefinition
Thread dump
14. Deoptimization
When speculative optimization fails:
HotSpot rewrites machine code frame → interpreter frame
Continues execution safely
Example:
JIT assumed a method returns int → but at runtime a string appears → triggers deoptimization.
15. Summary Table
Component Description
Interpreter Executes bytecode initially
JIT (C1/C2) Compiles hot methods to machine code
Tiered Compilation Combines C1 fast compile + C2 aggressive optimization
Code Cache Stores native compiled code
ClassLoader Loads, verifies, and initializes classes
GC Manages heap memory
Runtime Profiling Provides feedback for optimizations
Deoptimization Reverts optimized code when assumptions break
Final Diagram: HotSpot End-to-End
Execution
Java Source (.java)
↓
Javac Compiler
↓
Bytecode (.class)
↓
ClassLoader → Verification
↓
Interpreter
↓
Profiling (HotSpot)
↓
JIT Compilation (C1 → C2)
↓
Optimized Native Code
↓
GC + Runtime Services
↓
Execution Complete