JVM Architecture: Complete Deep Dive with Diagrams
Comprehensive guide to Java Virtual Machine architecture covering class loading, memory management, garbage collection, execution engine, and performance tuning with detailed diagrams and data flow charts
JVM Architecture: Complete Deep Dive
Learning Objectives
By the end of this guide, you will master:
✅ JVM internals and architecture components
✅ Memory areas and their purposes
✅ Class loading process with parent delegation
✅ Execution engine (Interpreter & JIT)
✅ Garbage collection algorithms
✅ Memory leak analysis and troubleshooting
✅ JVM tuning for production
✅ Cloud & Kubernetes optimization
1. What is JVM?
The Java Virtual Machine (JVM) is an abstract computing machine that executes Java bytecode, enabling platform independence.
Java Execution Flow
┌─────────────────┐
│ Java Source │
│ (.java) │
└────────┬────────┘
│ javac
▼
┌─────────────────┐
│ Bytecode │
│ (.class) │
└────────┬────────┘
│
▼
┌─────────────────┐
│ JVM │
│ (Platform │
│ Independent) │
└────────┬────────┘
│
▼
┌─────────────────┐
│ Operating System│
└────────┬────────┘
│
▼
┌─────────────────┐
│ Hardware │
└─────────────────┘
Key Benefit: "Write Once, Run Anywhere" (WORA)
2. JDK vs JRE vs JVM
┌─────────────────────────────────────┐
│ JDK │
│ + javac, jar, javadoc, jdb │
│ │
│ ┌───────────────────────────────┐ │
│ │ JRE │ │
│ │ + Class Libraries │ │
│ │ │ │
│ │ ┌─────────────────────────┐ │ │
│ │ │ JVM │ │ │
│ │ │ - Class Loader │ │ │
│ │ │ - Execution Engine │ │ │
│ │ │ - Runtime Data Areas │ │ │
│ │ └─────────────────────────┘ │ │
│ └───────────────────────────────┘ │
└─────────────────────────────────────┘
| Component | Purpose | Use Case |
|---|---|---|
| JDK | Development | Developing Java apps |
| JRE | Runtime | Running Java apps |
| JVM | Execution | Executing bytecode |
3. Complete JVM Architecture
┌────────────────────────────────────────────────┐
│ JVM ARCHITECTURE │
├────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────────────────────────┐ │
│ │ CLASS LOADER SUBSYSTEM │ │
│ │ │ │
│ │ Bootstrap → Extension → Application │ │
│ │ │ │
│ │ Loading → Linking → Initialization │ │
│ └────────────┬─────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────┐ │
│ │ RUNTIME DATA AREAS (MEMORY) │ │
│ │ │ │
│ │ ┌────────────────────────────────────┐ │ │
│ │ │ Method Area (Metaspace) │ │ │
│ │ │ - Class Metadata │ │ │
│ │ │ - Static Variables │ │ │
│ │ └────────────────────────────────────┘ │ │
│ │ │ │
│ │ ┌────────────────────────────────────┐ │ │
│ │ │ Heap Memory (Shared) │ │ │
│ │ │ ┌──────────┐ ┌──────────────┐ │ │ │
│ │ │ │Young Gen │ │ Old Gen │ │ │ │
│ │ │ │Eden,S0,S1│ │ Tenured │ │ │ │
│ │ │ └──────────┘ └──────────────┘ │ │ │
│ │ └────────────────────────────────────┘ │ │
│ │ │ │
│ │ ┌─────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ Stack │ │PC Register│ │ Native │ │ │
│ │ │(Thread) │ │ (Thread) │ │ Stack │ │ │
│ │ └─────────┘ └──────────┘ └──────────┘ │ │
│ └────────────┬─────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────┐ │
│ │ EXECUTION ENGINE │ │
│ │ │ │
│ │ ┌────────────┐ ┌──────────────────┐ │ │
│ │ │Interpreter │ │ JIT Compiler │ │ │
│ │ │ │ │ C1 + C2 │ │ │
│ │ └────────────┘ └──────────────────┘ │ │
│ │ │ │
│ │ ┌────────────────────────────────────┐ │ │
│ │ │ Garbage Collector │ │ │
│ │ │ Serial/Parallel/G1/ZGC │ │ │
│ │ └────────────────────────────────────┘ │ │
│ └────────────┬─────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────┐ │
│ │ Native Method Interface (JNI) │ │
│ └────────────┬─────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────┐ │
│ │ Native Libraries (C/C++) │ │
│ └──────────────────────────────────────────┘ │
└────────────────────────────────────────────────┘
4. Class Loader Subsystem
Class Loader Hierarchy
┌─────────────────────────────────┐
│ Bootstrap Class Loader │
│ (Native C/C++) │
│ Loads: rt.jar, core classes │
└──────────────┬──────────────────┘
│
▼
┌─────────────────────────────────┐
│ Extension Class Loader │
│ (Java) │
│ Loads: $JAVA_HOME/lib/ext │
└──────────────┬──────────────────┘
│
▼
┌─────────────────────────────────┐
│ Application Class Loader │
│ (System Class Loader) │
│ Loads: CLASSPATH classes │
└─────────────────────────────────┘
Parent Delegation Model
Request: Load com.example.MyClass
Step 1: App Loader checks cache → Not found
Step 2: Delegate to Extension → Not found
Step 3: Delegate to Bootstrap → Not found
Step 4: Bootstrap tries → Not found
Step 5: Extension tries → Not found
Step 6: App Loader loads → Found!
Step 7: Cache and return
Class Loading Phases
┌─────────────────────────────────┐
│ LOADING │
│ - Find .class file │
│ - Read binary data │
│ - Create Class object │
└──────────┬──────────────────────┘
│
▼
┌─────────────────────────────────┐
│ LINKING │
│ ┌───────────────────────────┐ │
│ │ Verification │ │
│ │ - Bytecode verification │ │
│ │ - Security checks │ │
│ └───────────────────────────┘ │
│ ┌───────────────────────────┐ │
│ │ Preparation │ │
│ │ - Allocate static memory │ │
│ │ - Set default values │ │
│ └───────────────────────────┘ │
│ ┌───────────────────────────┐ │
│ │ Resolution │ │
│ │ - Symbolic → Direct refs │ │
│ └───────────────────────────┘ │
└──────────┬──────────────────────┘
│
▼
┌─────────────────────────────────┐
│ INITIALIZATION │
│ - Execute static blocks │
│ - Initialize static variables │
└─────────────────────────────────┘
Example:
public class Demo {
static int counter = 100; // Preparation: 0, Init: 100
static {
System.out.println("Class loaded!");
counter = 200;
}
}
5. Runtime Data Areas
Memory Layout
┌────────────────────────────────────────────┐
│ JVM MEMORY STRUCTURE │
├────────────────────────────────────────────┤
│ │
│ METHOD AREA (Metaspace) - Shared │
│ ┌──────────────────────────────────────┐ │
│ │ - Class Metadata │ │
│ │ - Static Variables │ │
│ │ - Constant Pool │ │
│ └──────────────────────────────────────┘ │
│ │
│ HEAP MEMORY - Shared │
│ ┌──────────────────────────────────────┐ │
│ │ Young Generation (1/3) │ │
│ │ ┌────────────────────────────────┐ │ │
│ │ │ Eden (80%) │ │ │
│ │ │ new Object() created here │ │ │
│ │ └────────────────────────────────┘ │ │
│ │ ┌──────────┐ ┌──────────────────┐ │ │
│ │ │ S0 (10%) │ │ S1 (10%) │ │ │
│ │ └──────────┘ └──────────────────┘ │ │
│ └──────────────────────────────────────┘ │
│ ┌──────────────────────────────────────┐ │
│ │ Old Generation (2/3) │ │
│ │ Long-lived objects │ │
│ └──────────────────────────────────────┘ │
│ │
│ STACK - Per Thread │
│ ┌──────────┐ ┌──────────┐ │
│ │ Thread 1 │ │ Thread 2 │ │
│ │ ┌──────┐ │ │ ┌──────┐ │ │
│ │ │Frame3│ │ │ │Frame2│ │ │
│ │ ├──────┤ │ │ ├──────┤ │ │
│ │ │Frame2│ │ │ │Frame1│ │ │
│ │ ├──────┤ │ │ └──────┘ │ │
│ │ │Frame1│ │ │ │ │
│ │ └──────┘ │ │ │ │
│ └──────────┘ └──────────┘ │
│ │
│ PC REGISTER - Per Thread │
│ Stores current instruction address │
│ │
│ NATIVE METHOD STACK - Per Thread │
│ For native (C/C++) methods │
└────────────────────────────────────────────┘
Memory Comparison
| Area | Shared? | Purpose | Size Flag | Error |
|---|---|---|---|---|
| Heap | Yes | Objects | -Xms/-Xmx | OutOfMemoryError |
| Stack | No | Method calls | -Xss | StackOverflowError |
| Metaspace | Yes | Class metadata | -XX:MaxMetaspaceSize | OutOfMemoryError |
| PC Register | No | Instruction pointer | Fixed | None |
6. Heap Memory & Object Lifecycle
Heap Structure
┌─────────────────────────────────────────┐
│ HEAP MEMORY STRUCTURE │
├─────────────────────────────────────────┤
│ │
│ YOUNG GENERATION │
│ ┌───────────────────────────────────┐ │
│ │ EDEN SPACE (8/10) │ │
│ │ [Obj1] [Obj2] [Obj3] [Obj4] │ │
│ └───────────────────────────────────┘ │
│ ┌──────────────┐ ┌────────────────┐ │
│ │ SURVIVOR 0 │ │ SURVIVOR 1 │ │
│ │ (1/10) │ │ (1/10) │ │
│ │ [Obj:age=1] │ │ [Empty] │ │
│ └──────────────┘ └────────────────┘ │
│ │
│ ↓ Promotion (age >= 15) │
│ │
│ OLD GENERATION │
│ ┌───────────────────────────────────┐ │
│ │ [Obj:age=15] [Obj:age=20] ... │ │
│ │ Long-lived objects │ │
│ └───────────────────────────────────┘ │
└─────────────────────────────────────────┘
Object Lifecycle
new Object()
│
▼
┌─────────────────────┐
│ Created in Eden │
└──────┬──────────────┘
│ Eden Full
▼
┌─────────────────────┐
│ Minor GC │
│ Copy to Survivor 0 │
│ Age = 1 │
└──────┬──────────────┘
│ Next Minor GC
▼
┌─────────────────────┐
│ Copy to Survivor 1 │
│ Age++ │
└──────┬──────────────┘
│ Age >= 15
▼
┌─────────────────────┐
│ Promote to Old Gen │
└──────┬──────────────┘
│ Major GC
▼
┌─────────────────────┐
│ Removed if unused │
└─────────────────────┘
7. Garbage Collection
GC Fundamentals
Garbage Collection automatically reclaims memory from unreachable objects.
Object Reachability
GC Roots (Always Reachable):
- Local variables
- Static variables
- Active threads
- JNI references
GC Root
│
├──→ [Object A] ──→ [Object B]
│ │
│ └──→ [Object C]
│
└──→ [Object D]
Unreachable (Garbage):
[Object X] ──→ [Object Y]
↑ │
└──────────────┘
(Circular, but no GC Root)
GC Algorithms Detailed
1. Serial GC
Purpose: Single-threaded garbage collection Best For: Small applications, single-CPU machines, client applications
java -XX:+UseSerialGC -jar app.jar
Characteristics:
- Uses single thread for both Young and Old generation
- Stop-the-world pauses for all GC operations
- Low memory footprint
- Simple and predictable
When to Use:
- Applications with heap < 100MB
- Single-core machines
- Client-side applications
2. Parallel GC (Throughput Collector)
Purpose: Multi-threaded garbage collection for maximum throughput Best For: Batch processing, scientific computations, background tasks
java -XX:+UseParallelGC \
-XX:ParallelGCThreads=4 \
-XX:MaxGCPauseMillis=100 \
-jar app.jar
Characteristics:
- Multiple threads for Young generation (Parallel Scavenge)
- Multiple threads for Old generation (Parallel Old)
- Focuses on throughput over latency
- Stop-the-world for both Minor and Major GC
When to Use:
- Batch processing systems
- Data analytics applications
- When throughput > latency
- Multi-core servers
3. G1 GC (Garbage First) - Default since Java 9
Purpose: Balanced low-latency and high-throughput collector Best For: Large heaps (>4GB), general-purpose applications
java -XX:+UseG1GC \
-XX:MaxGCPauseMillis=200 \
-XX:G1HeapRegionSize=16m \
-XX:InitiatingHeapOccupancyPercent=45 \
-jar app.jar
Characteristics:
- Divides heap into equal-sized regions (1-32MB)
- Predictable pause times
- Concurrent marking phase
- Collects regions with most garbage first
- Suitable for heaps 4GB-64GB
Phases:
- Young GC: Collect Eden + Survivor regions
- Concurrent Marking: Mark live objects (concurrent)
- Mixed GC: Collect Young + some Old regions
- Full GC: Last resort (should be avoided)
When to Use:
- Heap size > 4GB
- Need predictable pause times
- General-purpose applications
- Microservices
4. ZGC (Z Garbage Collector) - Java 15+
Purpose: Ultra-low latency garbage collector Best For: Large heaps (8GB-16TB), latency-sensitive applications
java -XX:+UseZGC \
-XX:ZCollectionInterval=5 \
-XX:ZAllocationSpikeTolerance=2 \
-jar app.jar
Characteristics:
- Pause times < 10ms (typically 1-2ms)
- Concurrent compaction
- Colored pointers for object tracking
- Load barriers for concurrent operations
- Scales from 8GB to 16TB heap
Key Features:
- Concurrent Everything: Mark, relocate, compact
- Region-based: Similar to G1 but more flexible
- Load Barriers: Track object references during GC
- Colored Pointers: 64-bit pointers with metadata
When to Use:
- Trading applications
- Real-time systems
- Large heap applications (>100GB)
- When pause time < 10ms is critical
5. Shenandoah GC
Purpose: Low-pause-time garbage collector Best For: Large heaps, latency-sensitive applications
java -XX:+UseShenandoahGC \
-XX:ShenandoahGCHeuristics=adaptive \
-jar app.jar
Characteristics:
- Pause times < 10ms
- Concurrent compaction
- Brooks pointers for indirection
- Independent of heap size
- Works with heaps 100MB-100GB+
Key Features:
- Concurrent Evacuation: Move objects while app runs
- Brooks Pointers: Indirection for concurrent access
- Adaptive Heuristics: Automatic tuning
When to Use:
- Financial applications
- Gaming servers
- When consistent low latency is required
- Alternative to ZGC
GC Comparison Table
| Feature | Serial | Parallel | G1 GC | ZGC | Shenandoah |
|---|---|---|---|---|---|
| Threads | 1 | Multiple | Multiple | Multiple | Multiple |
| Pause Time | High (100ms+) | Medium (50-100ms) | Low (10-200ms) | Ultra-low (<10ms) | Ultra-low (<10ms) |
| Throughput | Low | High | Good | Excellent | Good |
| Heap Size | <100MB | 100MB-4GB | 4GB-64GB | 8GB-16TB | 100MB-100GB+ |
| Concurrent | No | No | Partial | Yes | Yes |
| Compaction | No | Yes | Yes | Yes | Yes |
| Default | No | No | Yes (Java 9+) | No | No |
| Best For | Small apps | Batch jobs | General use | Ultra-low latency | Low latency |
G1 GC Structure
┌─────────────────────────────────────────┐
│ G1 GC HEAP REGIONS │
├─────────────────────────────────────────┤
│ │
│ Heap divided into equal regions │
│ (1-32 MB each) │
│ │
│ ┌───┬───┬───┬───┬───┬───┬───┬───┐ │
│ │ E │ E │ S │ O │ O │ E │ H │ O │ │
│ └───┴───┴───┴───┴───┴───┴───┴───┘ │
│ ┌───┬───┬───┬───┬───┬───┬───┬───┐ │
│ │ O │ E │ O │ E │ S │ O │ E │ H │ │
│ └───┴───┴───┴───┴───┴───┴───┴───┘ │
│ │
│ E = Eden, S = Survivor │
│ O = Old, H = Humongous (large objs) │
│ │
│ Process: │
│ 1. Young GC (Eden + Survivor) │
│ 2. Concurrent Marking │
│ 3. Mixed GC (Young + some Old) │
│ 4. Full GC (avoid!) │
└─────────────────────────────────────────┘
GC Configuration
# Serial GC
java -XX:+UseSerialGC -jar app.jar
# Parallel GC
java -XX:+UseParallelGC -XX:ParallelGCThreads=4 -jar app.jar
# G1 GC (Default)
java -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -jar app.jar
# ZGC (Java 15+)
java -XX:+UseZGC -jar app.jar
# Shenandoah
java -XX:+UseShenandoahGC -jar app.jar
8. Execution Engine
Execution Flow
┌─────────────────────────────────────────┐
│ EXECUTION ENGINE │
├─────────────────────────────────────────┤
│ │
│ BYTECODE │
│ ┌───────────────────────────────────┐ │
│ │ 0: aload_0 │ │
│ │ 1: getfield #2 │ │
│ │ 4: iload_1 │ │
│ │ 5: iadd │ │
│ │ 6: ireturn │ │
│ └──────────┬────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────────────────┐ │
│ │ INTERPRETER │ │
│ │ - Line-by-line execution │ │
│ │ - Slow but immediate start │ │
│ └──────────┬────────────────────────┘ │
│ │ Profiling │
│ ▼ │
│ ┌───────────────────────────────────┐ │
│ │ JIT COMPILER │ │
│ │ ┌─────────┐ ┌────────────────┐ │ │
│ │ │C1 (Fast)│ │C2 (Optimized) │ │ │
│ │ └─────────┘ └────────────────┘ │ │
│ └──────────┬────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────────────────┐ │
│ │ NATIVE CODE │ │
│ │ - Direct CPU execution │ │
│ │ - Maximum performance │ │
│ └───────────────────────────────────┘ │
└─────────────────────────────────────────┘
JIT Compilation Levels
Invocations 1-100:
Interpreter (Level 0)
│
▼
Invocations 100-1000:
C1 Compiler (Levels 1-3)
Quick compilation
│
▼
Invocations 1000+:
C2 Compiler (Level 4)
Aggressive optimization
│
▼
Cached Native Code
JIT Optimizations
- Inlining: Embed method calls
- Dead Code Elimination: Remove unused code
- Loop Unrolling: Reduce loop overhead
- Escape Analysis: Stack allocation
- Lock Elision: Remove unnecessary locks
- Constant Folding: Compile-time calculations
9. Stack vs Heap
Memory Allocation
public void processOrder(int orderId) {
String name = "John"; // Stack
Order order = new Order(); // Heap
order.setId(orderId); // Stack (orderId)
}
┌──────────────────┐ ┌──────────────────┐
│ STACK MEMORY │ │ HEAP MEMORY │
│ (Thread-local) │ │ (Shared) │
│ │ │ │
│ ┌────────────┐ │ │ ┌────────────┐ │
│ │processOrder│ │ │ │Order Object│ │
│ ├────────────┤ │ │ │ id = 123 │ │
│ │orderId=123 │ │ │ │ name=... │ │
│ │name ───────┼──┼──┼─→│ │ │
│ │order ──────┼──┼──┼─→│ │ │
│ └────────────┘ │ │ └────────────┘ │
│ │ │ │
│ Fast, LIFO │ │ Slower, GC │
│ Auto cleanup │ │ managed │
└──────────────────┘ └──────────────────┘
10. Memory Errors
OutOfMemoryError
// Heap OOM
List<Object> list = new ArrayList<>();
while(true) {
list.add(new Object());
}
// Metaspace OOM
while(true) {
// Generate classes dynamically
}
Causes:
- Memory leaks
- Insufficient heap size
- Large object allocation
- Too many classes loaded
StackOverflowError
void recursiveMethod() {
recursiveMethod(); // Infinite recursion
}
Causes:
- Deep/infinite recursion
- Large local variables
- Insufficient stack size
11. Memory Leak Analysis
Common Causes
// 1. Static Collections
static List<Employee> cache = new ArrayList<>();
// 2. Unclosed Resources
Connection conn = getConnection();
// Forgot to close!
// 3. ThreadLocal Misuse
ThreadLocal<User> userContext = new ThreadLocal<>();
// Not removed after use
// 4. Event Listeners
button.addListener(listener);
// Not removed when done
Detection Tools
# Heap Dump
jmap -dump:format=b,file=heap.bin <pid>
# Thread Dump
jstack <pid> > threads.txt
# GC Logs
java -Xlog:gc*:file=gc.log -jar app.jar
# JVM Info
jcmd <pid> VM.info
12. JVM Monitoring Tools
| Tool | Purpose | Command |
|---|---|---|
| jps | List JVM processes | jps -l |
| jstack | Thread dump | jstack <pid> |
| jmap | Heap dump | jmap -dump:file=heap.bin <pid> |
| jstat | GC statistics | jstat -gc <pid> 1000 |
| jcmd | Diagnostics | jcmd <pid> GC.heap_info |
| VisualVM | GUI monitoring | Launch VisualVM |
| JConsole | JMX monitoring | Launch JConsole |
13. JVM Tuning
Heap Configuration
# Initial and Maximum Heap
java -Xms512m -Xmx2g -jar app.jar
# Young Generation
java -Xmn512m -jar app.jar
# Metaspace
java -XX:MaxMetaspaceSize=512m -jar app.jar
# Stack Size
java -Xss1m -jar app.jar
GC Tuning
# G1 GC with pause time goal
java -XX:+UseG1GC \
-XX:MaxGCPauseMillis=200 \
-XX:G1HeapRegionSize=16m \
-jar app.jar
# Enable GC Logging
java -Xlog:gc*:file=gc.log:time,uptime,level,tags \
-jar app.jar
# Print GC Details
java -XX:+PrintGCDetails \
-XX:+PrintGCDateStamps \
-jar app.jar
14. JVM in Cloud & Kubernetes
Container-Aware JVM
# Enable container support (Java 10+)
java -XX:+UseContainerSupport \
-XX:MaxRAMPercentage=75.0 \
-jar app.jar
# Set CPU limits
java -XX:ActiveProcessorCount=2 \
-jar app.jar
Kubernetes Best Practices
resources:
requests:
memory: "512Mi"
cpu: "500m"
limits:
memory: "1Gi"
cpu: "1000m"
# JVM flags
env:
- name: JAVA_OPTS
value: "-Xms512m -Xmx768m -XX:+UseG1GC"
Monitoring in Production
Monitor:
├── Heap Usage
├── GC Frequency & Duration
├── Thread Count
├── CPU Usage
├── Response Time
└── Error Rate
15. Interview Questions
Basic
- Explain JVM Architecture
- Difference between Heap and Stack?
- What is Metaspace?
- How does Class Loader work?
Intermediate
- Explain Parent Delegation Model
- What is JIT Compiler?
- How does G1 GC work?
- Difference between Minor and Major GC?
Advanced
- What causes OutOfMemoryError?
- How do you analyze memory leaks?
- Explain Thread Dump vs Heap Dump
- Why is JVM suitable for microservices?
- How does JVM behave in containers?
- Explain ZGC vs G1GC
Detailed Answers
Q1: Explain JVM Architecture
Answer:
JVM architecture consists of three main subsystems:
-
Class Loader Subsystem: Loads, links, and initializes classes using parent delegation model (Bootstrap → Extension → Application)
-
Runtime Data Areas (Memory):
- Heap: Stores objects (shared)
- Stack: Method calls, local variables (per thread)
- Method Area (Metaspace): Class metadata, static variables
- PC Register: Current instruction (per thread)
- Native Method Stack: Native methods (per thread)
-
Execution Engine:
- Interpreter: Line-by-line execution
- JIT Compiler: Compiles hot code to native
- Garbage Collector: Automatic memory management
Flow: Java Source → Bytecode → Class Loader → Memory → Execution Engine → Native Code
Q2: Difference between Heap and Stack?
Answer:
| Aspect | Heap | Stack |
|---|---|---|
| Purpose | Objects, arrays | Method calls, local vars |
| Scope | Shared (all threads) | Per thread |
| Size | Larger (-Xms/-Xmx) | Smaller (-Xss, 1MB) |
| Lifecycle | Until GC | Method return |
| Access | Slower | Faster (LIFO) |
| Management | GC | Automatic |
| Error | OutOfMemoryError | StackOverflowError |
Q3: What is Metaspace?
Answer:
Metaspace replaced PermGen in Java 8+. It stores class metadata in native memory (not heap).
Key Differences:
- Location: Native memory (vs PermGen in heap)
- Size: Auto-grows (vs fixed PermGen)
- OOM: Rare (vs common in PermGen)
- GC: More efficient
Configuration: -XX:MaxMetaspaceSize=512m
Q4: How does Class Loader work?
Answer:
Three phases:
- Loading: Find .class, read binary, create Class object
- Linking: Verification → Preparation → Resolution
- Initialization: Execute static blocks, initialize static variables
Q5: Explain Parent Delegation Model
Answer:
Class loader delegates to parent before loading itself:
Bootstrap (top) → Extension → Application (bottom)
Process: Application delegates to Extension → Extension delegates to Bootstrap → Bootstrap tries → if not found, Extension tries → if not found, Application loads
Benefits: Security, uniqueness, consistency
Q6: What is JIT Compiler?
Answer:
JIT (Just-In-Time) compiles frequently executed bytecode to native code.
Levels:
- Level 0: Interpreter (0-100 invocations)
- Levels 1-3: C1 Compiler (100-1000 invocations)
- Level 4: C2 Compiler (1000+ invocations, aggressive optimization)
Optimizations: Inlining, dead code elimination, loop unrolling, escape analysis
Q7: How does G1 GC work?
Answer:
G1 (Garbage First) divides heap into equal regions (1-32MB).
Phases:
- Young GC: Collect Eden + Survivor (fast, 10-50ms)
- Concurrent Marking: Mark live objects (concurrent)
- Mixed GC: Collect Young + some Old regions
- Full GC: Last resort (avoid!)
Strategy: Collects regions with most garbage first
Configuration: -XX:+UseG1GC -XX:MaxGCPauseMillis=200
Q8: Difference between Minor and Major GC?
Answer:
| Aspect | Minor GC | Major GC |
|---|---|---|
| Target | Young Generation | Old + Young |
| Frequency | Very frequent | Infrequent |
| Duration | Fast (1-50ms) | Slow (100ms+) |
| Algorithm | Copy | Mark-Sweep-Compact |
| Impact | Low | High (pause) |
Q9: What causes OutOfMemoryError?
Answer:
Causes:
- Heap OOM: Memory leaks, insufficient heap
- Metaspace OOM: Too many classes
- GC Overhead: >98% time in GC, <2% heap recovered
- Native Thread: Too many threads
Solutions: Increase heap, fix leaks, optimize code, use profilers
Q10: How do you analyze memory leaks?
Answer:
Steps:
- Monitor:
jstat -gc <pid> 1000(watch Old Gen growth) - Heap Dump:
jmap -dump:file=heap.bin <pid> - Analyze: Use Eclipse MAT or VisualVM
- Fix: Remove static collections, close resources, clear ThreadLocal
Common Patterns: Static collections, unclosed resources, ThreadLocal misuse, event listeners
Q11: Explain Thread Dump vs Heap Dump
Answer:
| Aspect | Thread Dump | Heap Dump |
|---|---|---|
| Purpose | Thread states | Memory usage |
| Contains | Stack traces | Object instances |
| Size | Small (KB-MB) | Large (GB) |
| Use Case | Deadlocks, hangs | Memory leaks, OOM |
| Tool | jstack | jmap |
Q12: Why is JVM suitable for microservices?
Answer:
Reasons:
- Platform Independence: Write once, run anywhere
- Mature Ecosystem: Spring Boot, Micronaut, Quarkus
- Performance: JIT compilation, efficient GC
- Observability: Built-in monitoring (JMX, heap dumps)
- Container Support: Container-aware since Java 10
- Scalability: Horizontal scaling, stateless design
Q13: How does JVM behave in containers?
Answer:
Container-Aware (Java 10+):
- Respects cgroup memory limits
- Detects CPU limits
- Sets heap based on container memory
Configuration:
java -XX:+UseContainerSupport \
-XX:MaxRAMPercentage=75.0 \
-jar app.jar
Best Practices: Use percentage instead of fixed size, enable container support, monitor resources
Q14: Explain ZGC vs G1GC
Answer:
| Feature | G1 GC | ZGC |
|---|---|---|
| Pause Time | 10-200ms | <10ms (1-2ms) |
| Heap Size | 4GB-64GB | 8GB-16TB |
| Concurrent | Partial | Fully |
| Maturity | Mature | Newer |
| Use Case | General | Ultra-low latency |
Use G1 for general apps (4-64GB heap)
Use ZGC for ultra-low latency (>100GB heap)
Q15: What are JIT optimization techniques?
Answer:
Major Optimizations:
- Inlining: Embed method calls
- Dead Code Elimination: Remove unused code
- Loop Unrolling: Reduce loop overhead
- Escape Analysis: Stack allocation for local objects
- Lock Elision: Remove unnecessary synchronization
- Constant Folding: Compile-time calculations
- Branch Prediction: Optimize frequent branches
- Intrinsics: Replace with CPU-specific instructions
Example: Method call → Inlined → Dead code removed → Constant folded → Native code 15. What are JIT optimization techniques?
16. Key Takeaways
✅ JVM provides platform independence through bytecode
✅ Class Loader uses parent delegation for security
✅ Heap stores objects, Stack stores method calls
✅ G1 GC is default, ZGC for low-latency
✅ JIT compiles hot code to native for performance
✅ Monitor heap, GC, threads in production
✅ Tune JVM for container environments
✅ Analyze memory leaks with heap dumps
Master JVM architecture to build high-performance, scalable Java applications! 🚀