.
java (source code)
↓
javac (JDK compiler)
■■ lexical checking
■■ syntax checking
■■ semantic/type checking
↓
.class (binary bytecode file)
■■ bytecode instructions
■■ constant pool
■■ metadata
(bytecode is binary, hex is only display)
-----------------------------------------
OS creates JVM process
■■ native process thread created (entry thread)
■■ loads JVM shared library ([Link] / [Link])
↓
Control enters JVM bootstrap
-----------------------------------------
JVM Bootstrap
■■ Runtime Data Areas created
■ ■■ Heap
■ ■■ Method Area / Metaspace
■ ■■ Code Cache
■ ■■ Java Stack(s)
■ ■■ PC Register(s)
■ ■■ Native Method Stack(s)
■
■■ Template Interpreter initialized
■ (native machine code handlers prepared)
■
■■ Codelets generated
(small native snippets for each bytecode
stored in executable memory)
-----------------------------------------
OS native entry thread
↓ (wrapped by JVM)
Java-level main thread created
■■ Java Stack allocated
■■ PC Register allocated
■■ Native Method Stack allocated
(this thread performs class loading)
-----------------------------------------
Class Loading (performed by main thread)
■■ Loading phase
■ ■■ .class read as byte stream
■ ■■ parsed into runtime structures
■ ■ ■■ runtime constant pool
■ ■ ■■ method structures
■ ■ ■■ field tables
■ ■ ■■ attribute tables
■ ■ (still bytecode but organized)
■ ■ → stored in Metaspace
■ ■
■ ■■ Class object created (Heap)
■ ([Link])
■
■■ Linking phase
■ ■■ Verification (bytecode safety)
■ ■■ Preparation
■ ■ ■■ static memory defaulted
■ ■ (0 / null / false)
■ ■■ Resolution
■ ■■ symbolic refs replaced with
■ direct refs (search Method Area)
■
■■ Initialization phase
■■ static fields assigned actual values
■■ static blocks executed (<clinit>)
-----------------------------------------
Execution Engine
■■ Locate:
■ public static void main(String[])
■
■■ First stack frame created (main)
■■ PC Register set → first bytecode of main
-----------------------------------------
Interpreter Execution Cycle
Loop:
■■ Read PC register
■■ Fetch next bytecode opcode
■■ Dispatch table lookup
■■ Find corresponding CODELET
■■ Jump to that memory address
■ (IP changed)
■■ CPU executes native instructions
■■ Return to interpreter loop
■■ PC updated
(Interpreter does NOT generate code
does NOT pass code to CPU
only transfers control via IP jump)
-----------------------------------------
JIT Compilation (while interpreting)
■■ Hot methods detected
■■ Compiled into native machine code
■■ Stored in Code Cache
Later method calls:
■■ IP ← native method entry (Code Cache)
(interpreter bypassed)
-----------------------------------------
CPU executes native instructions
(from codelets or JIT compiled code)
-----------------------------------------
If system service needed (e.g. println)
Native execution
↓
JVM runtime native stub
↓
JNI bridge
↓
Shared Library (C/C++)
↓
OS syscall
↓
Terminal / File / Network
-----------------------------------------
Garbage Collector
■■ manages Heap
(removes unreachable objects)
-----------------------------------------
Program Output