Skip to content
intermediatePhase 16 · Java Memory & JVM

Stack vs Heap

Understand where variables, objects, and references live in memory.

45m
2 problems
Topic Progress0%

Stack Memory

Stack Memory in Java

The stack is a region of memory used for static memory allocation. It stores:

  • Local variables (primitives)
  • Method call frames
  • Reference variables (the references, NOT the objects)
  • Partial results

Each thread has its own private stack. The stack follows LIFO (Last In, First Out) order.

public class StackDemo {
    public static void main(String[] args) {
        int x = 10;           // x lives on stack
        double y = 3.14;      // y lives on stack
        String name = "Java"; // reference on stack, object on heap
        
        calculate(x, y);      // new stack frame created
    }
    
    public static double calculate(int a, double b) {
        int result = a * 2;   // result lives on this stack frame
        return result + b;    // stack frame destroyed after return
    }
}

Key characteristics:

  • Fast access
  • Size limited (usually 512KB - 1MB)
  • Automatically managed
  • Thread-safe (each thread has its own)
  • Stores only primitives and references

Heap Memory

Heap Memory in Java

The heap is used for dynamic memory allocation. It stores:

  • All objects created with new
  • Arrays
  • Instance variables (fields of objects)
  • Static variables

The heap is shared among all threads in the JVM.

public class HeapDemo {
    static int count = 0;           // static variable on heap
    
    public static void main(String[] args) {
        // Objects on heap:
        Person p1 = new Person("Alice", 30);  // Person object on heap
        Person p2 = new Person("Bob", 25);    // Person object on heap
        int[] numbers = new int[10];           // array on heap
        
        // What's on stack:
        // - p1, p2 (references to heap objects)
        // - numbers (reference to array)
    }
}

class Person {
    String name;  // instance variable (on heap with the object)
    int age;      // instance variable (on heap with the object)
    
    Person(String name, int age) {
        this.name = name;  // String object on heap
        this.age = age;
    }
}

Key characteristics:

  • Slower access than stack
  • Size can be large (GB)
  • Managed by Garbage Collector
  • Shared among all threads
  • Stores objects and their instance data

Stack Frames

Stack Frames

Every time a method is called, a new stack frame is created and pushed onto the stack. The frame contains:

  1. Local variables for the method
  2. Parameters passed to the method
  3. Return address
  4. Operand stack
public class StackFrameDemo {
    public static void main(String[] args) {
        int result = factorial(5);
    }
    
    public static int factorial(int n) {
        if (n <= 1) return 1;    // Base case
        return n * factorial(n - 1);  // Recursive call
    }
}

// Stack frames during execution:
// |------------------|
// | factorial(1)     |  <- n=1, returns 1
// | factorial(2)     |  <- n=2
// | factorial(3)     |  <- n=3
// | factorial(4)     |  <- n=4
// | factorial(5)     |  <- n=5
// | main()           |  <- args
// |------------------|
// Stack grows downward

Each frame has its own copy of local variables. When a method returns, its frame is popped from the stack.

Memory Diagrams

Memory Diagram Examples

Understanding how memory is organized helps debug many Java issues.

Example 1: Object References

public class MemoryDiagramExample {
    public static void main(String[] args) {
        Point p1 = new Point(1, 2);
        Point p2 = p1;  // Both point to same object!
        
        p2.x = 100;  // This changes p1.x too!
        System.out.println(p1.x);  // 100, not 1
        
        p1 = new Point(5, 6);  // p1 now points to new object
        System.out.println(p2.x);  // Still 100
    }
}

class Point {
    int x, y;
    Point(int x, int y) { this.x = x; this.y = y; }
}

// Stack          Heap
// p1  ──────────> Point(1, 2)  <- shared!
// p2  ──────────/

Example 2: Array Memory

public class ArrayMemory {
    public static void main(String[] args) {
        int[] arr1 = {1, 2, 3};
        int[] arr2 = arr1;  // Same array!
        
        arr2[0] = 999;  // Changes arr1 too
        System.out.println(arr1[0]);  // 999
    }
}
// Stack          Heap
// arr1 ──────────> [999, 2, 3]
// arr2 ──────────/

Key takeaway: References are copied, not objects. Two references can point to the same object.

Interview Questions

Interview Questions

Q: Where does a local variable of type String live?

A: The reference lives on the stack. The actual String object lives on the heap.

void example() {
    String s = "Hello";  // Reference 's' on stack
                          // "Hello" String object on heap
}

Q: Can you access stack memory from another thread?

A: No. Each thread has its own private stack. This makes stack variables thread-safe by default.

Q: What happens when stack memory is exhausted?

A: StackOverflowError is thrown. Common causes: infinite recursion or very deep recursion.

void infinite() {
    infinite();  // StackOverflowError!
}

Q: What is the difference between new String("hello") and "hello"?

A: new String("hello") creates a new object on the heap. "hello" uses the string pool (also heap, but shared).

Q: Why is stack faster than heap?

A: Stack uses LIFO allocation with no GC needed. Just move a pointer. Heap requires allocation, garbage collection, and more complex management.

Practice Problems

0/2solved
Trace Memory Allocation

Given the following code, draw the stack and heap memory state after line 5: ```java int x = 5; int[] arr = {1, 2, 3}; String s = "hello"; Object obj = new Object(); int[] arr2 = arr; ```

Solution
```java
// Stack:
// x = 5 (primitive)
// arr -> [1,2,3] on heap
// s -> "hello" in string pool
// obj -> Object on heap
// arr2 -> [1,2,3] on heap (same as arr)
```
Stack holds: x (value 5), arr (reference), s (reference), obj (reference), arr2 (reference).
Heap holds: array [1,2,3], String "hello" in pool, Object instance.
Predict StackOverflowError

Explain why this code throws StackOverflowError and how many stack frames are created: ```java public static int method(int n) { if (n == 0) return 0; return method(n - 1) + 1; } method(10000); ```

Solution
Each recursive call creates a new stack frame on the call stack. With `method(10000)`, 10000+ frames are created. The default stack size (typically 512KB-1MB) cannot hold this many frames, causing StackOverflowError. Fix: use iteration, or increase stack size with `-Xss` flag, or use tail recursion optimization (not supported in Java).

Quiz

1. Where are primitive local variables stored in Java?

Question 1 options

2. What happens when two references point to the same object?

Question 2 options

3. What error occurs when stack memory is exhausted?

Question 3 options

4. Which statement about Java stack memory is TRUE?

Question 4 options

Flashcards

Question

What is stored on the Java stack?

Answer

Local variables (primitives), method call frames, reference variables, and partial results.

Question

What is stored on the Java heap?

Answer

All objects created with `new`, arrays, instance variables, and static variables.

Question

What is a stack frame?

Answer

A block created on the stack for each method call, containing local variables, parameters, return address, and operand stack.

Question

What happens when you do `String a = b;`?

Answer

The reference is copied, not the object. Both `a` and `b` point to the same String object on the heap.

Question

What is Stack vs Heap Memory in Java?

Answer

Stack vs Heap Memory in Java is a key concept in Java programming.

Revision Notes

Key Takeaways

  • 1.Stack stores primitives and references; heap stores objects
  • 2.Each thread has its own stack; heap is shared
  • 3.References are copied, not objects
  • 4.StackOverflowError occurs from deep recursion

Interview Tips

  • Always mention that references are copied, not objects
  • Draw memory diagrams when explaining object sharing
  • Explain why String immutability matters for memory sharing
  • Mention that stack is faster due to LIFO allocation

Cheat Sheet

Stack vs Heap Cheat Sheet

Stack Memory

  • Fast, LIFO
  • Private to each thread
  • Stores primitives & references
  • No GC needed
  • Size: ~512KB-1MB

Heap Memory

  • Slow, shared
  • Stores all objects
  • Managed by GC
  • Size: GBs

Key Rules

  • new creates object on heap
  • References are on stack
  • Two refs can share one object
  • StackOverflowError = stack full
  • OutOfMemoryError = heap full