Java Memory Model: Stack, Heap, and Pass-by-Value Myths
The Foundation of Java Execution
Where does a variable live? How does it get passed to a method? These questions are at the heart of performance and bug-prevention in Java.
Core Concepts
1. The Stack
- Used For: Local variables and method execution.
- Characteristics: Fast, automatically managed (LIFO), thread-private. If a thread exceeds its stack size, you get a
StackOverflowError.
2. The Heap
- Used For: All objects (including class instances and arrays).
- Characteristics: Shared by all threads, managed by the Garbage Collector. If full, you get an
OutOfMemoryError.
3. Pass-by-Value (The Great Debate)
Java is always pass-by-value.
- For Primitives, you pass a copy of the value.
- For Objects, you pass a copy of the Reference (which is just a memory address value).
Practice Exercise: Proving the Reference Myth
We will write code to demonstrate that you can modify an object’s contents inside a method, but you cannot change which object the original variable points to.
Step 1: The Experiment
public class MemoryDemo {
public static void main(String[] args) {
User u = new User("Old Name");
modify(u);
System.out.println(u.name); // Will it change?
reassign(u);
System.out.println(u.name); // Will it change?
}
public static void modify(User user) {
user.name = "New Name"; // Modifying state via the reference
}
public static void reassign(User user) {
user = new User("Reset Name"); // Reassigning the local copy of the reference
}
}
Output:
New Name(The content was modified).New Name(The originalustill points to the first object; the reassignment insidereassignonly affected the local variableuser).
Why This Works
- Stack for References: In the example, the variable
ulives on themainmethod’s stack frame. It holds a value (e.g.,0x123) which is the address of the Object on the Heap. - Passing the Reference: When
modify(u)is called, the value0x123is copied into theuserparameter. Both now point to the same object. - Isolating Reassignment: When we do
user = new User(...), the local variableusernow holds a different value (e.g.,0x456), but the original stack variableustill holds0x123.
Performance Tip: Escaping Objects
If an object is only used within a single method and doesn’t “escape” (i.e., it’s not returned or assigned to a field), the modern JVM (HotSpot) can perform Escape Analysis and allocate that object on the Stack instead of the Heap. This significantly reduces GC pressure.
Summary
Stack = Execution. Heap = Data. Understanding how Java handles references allows you to write predictable, memory-efficient code and avoids the “magic” confusion often associated with method calls.