What is the difference between Heap and Stack memory in Java?
In Java, memory is divided into two primary regions: the stack and the heap.
Stack memory is allocated per thread. It stores method call frames, each containing local variables, parameters, and the return address. When a method is called, a new frame is pushed; when it returns, the frame is popped and memory is instantly reclaimed. This makes stack allocation extremely fast — just a pointer adjustment. Local primitive variables live entirely on the stack. Local reference variables also live on the stack, but they point to objects on the heap. Stack size is typically small (512KB to 1MB by default, configurable with -Xss). If a thread's stack runs out of space, Java throws a StackOverflowError.
Heap memory is shared across all threads. It is where all objects and their instance variables are stored via the new keyword. The heap is managed by the garbage collector, which periodically reclaims objects no longer reachable from any live reference. The heap is divided into generations: young generation (Eden + Survivor spaces) for short-lived objects, and old generation for long-lived objects. Heap size is configurable with -Xms (initial) and -Xmx (maximum). When exhausted, Java throws OutOfMemoryError.
The distinction has important implications for thread safety. Stack memory is inherently thread-safe because each thread has its own stack. Heap memory is shared, so objects on the heap need synchronization for concurrent access.
The JVM can perform escape analysis to determine if an object created inside a method never escapes that method's scope. If so, the JVM may allocate it on the stack instead of the heap (scalar replacement), avoiding GC overhead entirely.
| Aspect | Stack Memory | Heap Memory |
|---|---|---|
| Scope | Per-thread, private | Shared across all threads |
| Stores | Local variables, method frames, references | Objects and their instance fields |
| Allocation speed | Very fast (pointer adjustment) | Slower (GC-managed) |
| Deallocation | Automatic on method return (LIFO) | Garbage collector |
| Size | Small, fixed per thread (-Xss) | Large, configurable (-Xms, -Xmx) |
| Error on exhaustion | StackOverflowError | OutOfMemoryError |
| Thread safety | Inherently safe (thread-private) | Requires explicit synchronization |
Correctly identifies what is stored in each, explains that stack is per-thread and heap is shared, and mentions the two error types.
Covers storage contents, allocation/deallocation mechanisms, thread isolation vs sharing, error types with causes, GC and generational heap structure, escape analysis, and JVM tuning parameters.
Reading the answer is step one. Explaining it unprompted — under interview pressure — is what actually matters. Get AI-graded feedback on your answer with follow-up probes on your weak points.
Get Graded — Free Assessment