JVM Architecture (Java Virtual Machine)
The Java Virtual Machine (JVM) Architecture defines how Java code is loaded, verified, executed, and managed in memory. It consists of three core components:
_20251117_080230.png&w=3840&q=75)
- Class Loader Subsystem
- Runtime Data Areas (Memory Structure)
- Execution Engine (Interpreter + JIT + GC)
This architecture ensures Java’s platform independence, automatic memory management, and high performance.
1. Class Loader Subsystem
The Class Loader is responsible for loading Java classes into the JVM.
It loads .class (bytecode) files dynamically at runtime.
Key Responsibilities
- Loading classes into memory
- Verifying bytecode security
- Preparing memory for class variables
- Resolving references (links classes together)
Types of Class Loaders

- Bootstrap ClassLoader
- Loads core Java classes (
java.lang,java.util, etc.) - Part of native JVM code
- No Java object representation
- Loads core Java classes (
- Extension (Platform) ClassLoader
- Loads classes from JDK extensions
- Example:
jre/lib/ext/
- Application ClassLoader
- Loads application-level classes
- Loads everything from the project’s classpath
Class Loading Steps
- Loading – Reads
.classfile - Linking
- Verification → Ensures bytecode safety
- Preparation → Allocates memory for static fields
- Resolution → Replaces symbolic references
- Initialization
- Executes static blocks
- Initializes static variables
2. JVM Runtime Data Areas (Memory Structure)
JVM divides memory into different runtime areas where methods, objects, references, and instructions are stored.
JVM Memory Structure
_20251117_080454.png&w=3840&q=75)
1. Method Area / MetaSpace (Shared)
Stores class-level information:
- Class metadata
- Static variables
- Method & constructor definitions
- Constant Pool
MetaSpace (JDK 8+) grows dynamically → reduces OutOfMemory errors.
2. Heap Area (Shared)
Stores:
- Objects
- Arrays
- Instance variables
Heap is divided into:
- Young Generation (Eden + Survivor S0/S1)
- Old Generation
- Metaspace (class metadata)
Managed by Garbage Collector.
3. JVM Stack (Per Thread)
Each thread has its own stack.
Stores:
- Method call frames
- Local variables
- Reference variables
- Return values
Follows LIFO (Last In First Out).
4. PC Register (Per Thread)
Stores:
-
Address of the current instruction being executed
Every Java thread has its own PC register.
5. Native Method Stack
Used for:
- Executing native code (C/C++ via JNI)
- OS-level operations
3. Execution Engine (How JVM Executes Code)
The Execution Engine is responsible for executing the loaded bytecode.
Components of Execution Engine
1. Interpreter
- Executes bytecode line-by-line
- Slower, but starts immediately
- Used for non-frequent code paths
2. JIT Compiler (Just-In-Time)
- Converts repeatedly executed bytecode → native machine code
- Improves overall performance
- Works with a HotSpot Profiler to find frequently executed methods (hotspots)
Output: Faster execution on the CPU.
3. Garbage Collector (GC)
Automatically cleans unused objects from Heap.
Uses algorithms like:
- Mark & Sweep
- G1 GC
- ZGC
- Shenandoah
Improves memory efficiency and reduces leaks.
4. Native Method Interface (JNI)
Allows Java to interact with:
- C/C++ libraries
- OS-level functions
Complete JVM Architecture (Summary Diagram)
+-------------------------------+
| Class Loader |
+-------------------------------+
| Loading | Linking | Init
v
+-----------------------------------------------------+
| JVM Runtime Data Areas |
| |
| +------------+ +-------------------------------+ |
| | Method | | Heap | |
| | Area | | - Objects | |
| +------------+ | - Arrays | |
| +-------------------------------+ |
| +------------+ +-------------------------------+ |
| | JVM Stack | | PC Register | |
| +------------+ +-------------------------------+ |
| +------------+ |
| | Native | |
| | Stack | |
| +------------+ |
+-----------------------------------------------------+
|
v
+-----------------------+
| Execution Engine |
| Interpreter |
| JIT Compiler |
| Garbage Collector |
+-----------------------+
|
v
CPU / OS
Why JVM Architecture Matters
Understanding JVM internals helps in:
- Writing optimized, high-performance code
- Fixing memory leaks
- Understanding GC behaviour
- Improving multithreading & concurrency
- Performance tuning large applications
