Java Memory Model Explained
JVM Memory Structure — One Coherent Story, From First Principles
Java Memory Model Explained
JVM Memory Structure — One Coherent Story, From First Principles

Java Memory Model Explained
1. What Really Happens When Java Runs
ㅤ Let’s begin with a single line of Java:
User user = new User();
This line looks simple, but it forces the JVM to answer three fundamental questions:
- Where does code execute?
- Where does data live?
- How do multiple threads coexist safely?
Everything in the JVM memory structure exists to answer one of these questions.
2. The JVM’s First Big Decision: Private vs Shared Memory
ㅤㅤ When the JVM starts, it does not create one big memory pool.
Instead, it makes a critical architectural decision:
Some memory will be private to each thread, and some memory will be shared by all threads.
This decision explains almost the entire memory model.
┌──────────────────────────────────────────────┐
│ JVM MEMORY │
├──────────────────┬───────────────────────────┤
│ Thread-Private │ Thread-Shared │
├──────────────────┼───────────────────────────┤
│ Java Stack │ Heap │
│ PC Register │ Metaspace │
│ Native Stack │ │
└──────────────────┴───────────────────────────┘
Thread-private memory exists for speed and safety. Shared memory exists for communication.
3. How Java Executes Code: The Stack-Based Execution Model
ㅤ Before we talk about objects or memory leaks, we must understand how Java executes code.
Java execution is stack-based, not object-based.
3.1 One Stack Per Thread
ㅤ Every Java thread gets exactly one Java stack.
This stack exists solely to answer one question:
Which method is running, and what data does it need right now?
3.2 Stack Frames: The Real Unit of Execution
ㅤ Each method call creates a stack frame.
Think of a stack frame as a snapshot of a method’s execution state.
Stack Frame
├── Local Variables
├── Operand Stack
├── Return Address
└── Constant Pool Reference
Frames are pushed when a method starts and popped when it ends. No garbage collection is involved.
3.3 What the Stack Stores (And What It Never Stores)
ㅤ The stack stores:
- primitive values
- object references
The stack never stores objects themselves.
void example() {
int x = 10; // value on stack
User u = new User(); // reference on stack
}
The object lives somewhere else. That “somewhere else” is the heap.
3.4 Why Stack Memory Is Fast and Limited
ㅤ Stack memory is fast because:
- memory is contiguous
- allocation is simple push/pop
- no GC overhead
But each stack has a fixed size.
StackOverflowError
is the JVM telling you the stack ran out of space.
4. Where Data Lives: The Heap as Shared Object Memory
ㅤ Once code execution is clear, we can talk about data storage.
4.1 Why Java Needs a Heap
ㅤ Objects must:
- outlive a single method call
- be shared across threads
The stack cannot satisfy these requirements.
So Java uses a shared heap.
4.2 What Actually Lives in the Heap
ㅤ The heap stores:
- object instances
- instance fields
- arrays
- static field values
User user = new User();
user→ reference on stackUser object→ heap
5. The Heap Is Structured by Object Lifetime
ㅤ Early JVM designers observed something important:
Most objects die very quickly.
So instead of one large heap, Java organizes the heap by age.
Heap
├── Young Generation
│ ├── Eden
│ ├── Survivor S0
│ └── Survivor S1
└── Old Generation
This structure exists before garbage collection strategies are applied.
5.1 Eden: Where Objects Are Born
ㅤ All new objects start their life in Eden.
Allocation here is extremely fast because memory is contiguous and uses pointer bumping.
Most objects die here.
5.2 Survivor Spaces: Tracking Object Age
ㅤ Objects that survive Eden move to a survivor space.
Why two survivor spaces?
- to copy objects cleanly
- to avoid fragmentation
Objects move between S0 and S1, aging each time.
5.3 Old Generation: Long-Lived Objects
ㅤ Objects that survive long enough are promoted to the Old Generation.
These objects:
- are expensive to move
- are collected less frequently
Examples include caches and shared application state.
6. Memory About Classes: Metaspace
ㅤ So far we have talked about objects. But Java also needs memory for classes.
6.1 What Metaspace Stores
ㅤ Metaspace stores:
- class definitions
- method structures
- field metadata
- bytecode
- runtime constant pool
It does not store objects.
6.2 Why PermGen Was Removed
ㅤ Before Java 8, this data lived in PermGen.
PermGen caused frequent crashes due to fixed sizing.
Metaspace uses native memory and grows dynamically.
7. Small but Critical Thread-Specific Areas
ㅤ Some JVM memory areas are tiny but essential.
7.1 Program Counter (PC Register)
ㅤ Each thread has a PC register that stores the address of the current JVM instruction.
This allows the JVM to pause and resume threads correctly.
7.2 Native Method Stack
ㅤ When Java calls native (C/C++) code via JNI, execution uses the native stack.
This is invisible unless you work with JNI.
8. How Errors Map to Memory Structure
ㅤ Understanding structure lets you understand errors.
| Error | Meaning |
|-----------------------------------|-------------------------|
| StackOverflowError | Stack exhausted |
| OutOfMemoryError: Java heap space | Heap exhausted |
| OutOfMemoryError: Metaspace | Class metadata leak |
9. The Core Idea to Remember
- Stack stores method execution state
- Heap stores objects
- Young Gen handles short-lived objects
- Old Gen stores long-lived objects
- Metaspace stores class metadata
With this structure clear, garbage collection finally becomes intuitive.
What Comes Next
ㅤ Now that you understand where memory lives and why, Part 2 explains:
- how memory is reclaimed
- why different garbage collectors exist
- how Java balances throughput and latency
메타데이터
- post_id
- 0611aecabeec
- slug
- java-memory-model-explained-part-1-0611aecabeec
- url
- https://medium.com/javaguides/java-memory-model-explained-part-1-0611aecabeec
- canonical_url
- https://medium.com/javaguides/java-memory-model-explained-part-1-0611aecabeec
- author_url
- https://medium.com/@praneshmeher
- status
- ok
- fetched_at
- 2026-07-08 08:18:29