Lesson Completion
Back to course

JVM Architecture and Memory Structure: Understanding Java's Memory Model

Beginner
12 minutes4.7Java

1. The Hook (The "Byte-Sized" Intro)

  • In a Nutshell: JVM architecture has 3 main components: Class Loader (loads .class files), Runtime Data Areas (memory), Execution Engine (runs bytecode).
  • Memory areas: Heap (objects, shared, GC target), Stack (method frames, thread-specific, local variables), Metaspace (class metadata, replaces PermGen), PC Registers (thread instruction pointer), Native Method Stack (JNI calls).
  • Heap structure: Young Gen (Eden + 2 Survivors) + Old Gen.
  • Key: Heap = shared + slow, Stack = thread-local + fast!

Think of city infrastructure. Class Loader = immigration (brings newcomers). Heap = residential area (houses/objects, cleaned by garbage truck/GC). Stack = office cubicles (worker-specific, temporary). Metaspace = city blueprints (building codes/class metadata). PC Register = GPS (tracks where you are)!


2. Conceptual Clarity (The "Simple" Tier)

💡 The Analogy

  • Heap: Apartment complex (shared, managed, cleaned regularly)
  • Stack: Personal desk (fast access, yours only, auto-cleared)
  • Metaspace: Library (class definitions, rarely changes)

JVM Architecture

graph TD A[JVM] --> B[Class Loader<br/>Subsystem] A --> C[Runtime Data<br/>Areas] A --> D[Execution<br/>Engine] B --> B1[Bootstrap] B --> B2[Extension] B --> B3[Application] C --> C1[Heap<br/>Shared] C --> C2[Stack<br/>Per-thread] C --> C3[Metaspace<br/>Shared] C --> C4[PC Registers<br/>Per-thread] D --> D1[Interpreter] D --> D2[JIT Compiler] D --> D3[Garbage<br/>Collector] style C1 fill:#C2185B style C2 fill:#2E7D32 style C3 fill:#F57C00

Heap Memory Structure

graph TD A[Heap Memory] --> B[Young Generation] A --> C[Old Generation<br/>Tenured] B --> D[Eden Space<br/>New objects] B --> E[Survivor 0<br/>S0] B --> F[Survivor 1<br/>S1] style D fill:#2E7D32 style E fill:#F57C00 style F fill:#F57C00 style C fill:#C2185B

3. Technical Mastery (The "Deep Dive")

Runtime Data Areas Comparison

AreaShared?StoresGC?Size
Heap✅ YesObjects, arrays✅ Yes-Xms/-Xmx
Stack❌ No (per-thread)Local vars, frames❌ No-Xss
Metaspace✅ YesClass metadata⚠️ Rare-XX:MaxMetaspaceSize
PC Register❌ No (per-thread)Next instruction❌ NoSmall
Native Stack❌ No (per-thread)JNI calls❌ NoSmall

4. Interactive & Applied Code

java
public class JVMMemoryDemo { // Stored in METASPACE (class metadata) static int staticVar = 100; // Value in HEAP (or Metaspace for primitives) public static void main(String[] args) { demonstrateHeap(); demonstrateStack(); demonstrateMetaspace(); } // Heap vs Stack demonstration static void demonstrateHeap() { System.out.println("=== HEAP MEMORY ==="); // Objects go to HEAP Person p1 = new Person("Alice"); // Object in HEAP Person p2 = new Person("Bob"); // Another object in HEAP // Arrays go to HEAP int[] numbers = new int[1000]; // Array in HEAP // String objects in HEAP (String pool) String s1 = "Hello"; // String pool (HEAP) String s2 = new String("World"); // Regular heap System.out.println("Objects created in heap"); } static void demonstrateStack() { System.out.println("\n=== STACK MEMORY ==="); // Local variables in STACK int x = 10; // Primitive in STACK int y = 20; // Another primitive in STACK // Reference in STACK, object in HEAP Person p = new Person("Carol"); // 'p' (reference) in STACK // Person object in HEAP methodA(); // New frame pushed to stack // Frame popped when method returns } static void methodA() { int localVar = 5; // In this method's stack frame methodB(); // Another frame pushed } static void methodB() { int anotherVar = 10; // In this method's stack frame // Frame popped when returning } // Metaspace demonstration static void demonstrateMetaspace() { System.out.println("\n=== METASPACE ==="); // Class metadata stored in METASPACE Class<?> cls = Person.class; System.out.println("Class name: " + cls.getName()); System.out.println("Methods: " + cls.getMethods().length); // Static variables metadata in METASPACE System.out.println("Static var: " + staticVar); } } class Person { String name; // Instance variable (in HEAP with object) Person(String name) { this.name = name; } } // Stack Overflow demonstration class StackOverflowDemo { static int depth = 0; static void recursiveMethod() { depth++; recursiveMethod(); // Infinite recursion → StackOverflowError } public static void main(String[] args) { try { recursiveMethod(); } catch (StackOverflowError e) { System.out.println("Stack depth: " + depth); } } } // Memory monitoring class MemoryMonitoringDemo { public static void main(String[] args) { Runtime runtime = Runtime.getRuntime(); System.out.println("=== JVM MEMORY ==="); System.out.println("Max Memory (Heap): " + runtime.maxMemory() / 1024 / 1024 + " MB"); System.out.println("Total Memory: " + runtime.totalMemory() / 1024 / 1024 + " MB"); System.out.println("Free Memory: " + runtime.freeMemory() / 1024 / 1024 + " MB"); System.out.println("Used Memory: " + (runtime.totalMemory() - runtime.freeMemory()) / 1024 / 1024 + " MB"); } }

5. The Comparison & Decision Layer

HeapStack
Shared across threadsThread-specific
Objects, arraysPrimitives, references, frames
Slower accessFaster access
GC managedAuto-cleared on method return
Size: -Xms/-XmxSize: -Xss
OutOfMemoryErrorStackOverflowError

6. The "Interview Corner" (The Edge)

The "Killer" Interview Question: "Where are local variables stored? Heap or Stack?" Answer: It depends!

  • Primitive local variables: STACK
  • Object local variables: Reference in STACK, object in HEAP
java
void method() { int x = 10; // ✅ STACK (primitive) Person p = new Person(); // Reference 'p' in STACK // Person object in HEAP } // After method returns: // - Stack frame cleared (x and p reference gone) // - Person object in heap (eligible for GC if no other refs)

Pro-Tips:

  1. Young vs Old Gen:
text
Young Gen (Minor GC, frequent): - Eden: New objects start here - S0/S1: Survivors after GC - Objects promoted to Old Gen after ~15 GC cycles Old Gen (Major GC, infrequent): - Long-lived objects - Larger, slower GC
  1. PermGen → Metaspace (Java 8+):
bash
# Old (Java 7): Fixed size, OutOfMemoryError: PermGen -XX:PermSize=64m -XX:MaxPermSize=256m # New (Java 8+): Native memory, grows dynamically -XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=256m

Topics Covered

Java Fundamentals

Tags

#java#programming#beginner-friendly

Last Updated

2025-02-01