Java Memory Structure: Stack and Heap - Quiz
Total: 5 questions
1. What is the difference between the stack and the heap in Java?
What is the difference between the stack and the heap in Java?
The heap stores every object and array created with new, together with all their fields. The stack stores method call frames: local variables of primitive types, references to heap objects and method parameters.
The stack is LIFO: calling a method pushes a frame on top of the stack, returning pops it and frees the memory instantly, with no garbage collector involved. Heap memory is reclaimed by the garbage collector once an object is no longer reachable through any chain of references.
Each thread owns a private stack and it is small (configured with -Xss); there is a single heap per JVM and it is much larger (-Xms / -Xmx). Stack access is faster: no reference indirection and no GC work. Exhausting the stack throws StackOverflowError, exhausting the heap throws OutOfMemoryError: Java heap space.
2. Are object fields stored on the stack or in the heap? Is every object really allocated on the heap?
Are object fields stored on the stack or in the heap? Is every object really allocated on the heap?
All fields of an object, both primitive and reference ones, are stored inside the object itself, which means in the heap. The shortcut "primitives go on the stack" is only true for local variables of a method: an int x declared as a class field lives in the heap with the object.
An object is always created in the heap and only the reference to it sits on the stack — the value of a reference variable is the address of the object, not the object itself.
One nuance: the JIT compiler can perform escape analysis. If an object never escapes the method, the compiler may apply scalar replacement and keep its fields on the stack or in registers. That is a runtime optimization; it changes neither the memory model nor the way you write code.
3. Does Java pass objects to methods by reference or by value?
Does Java pass objects to methods by reference or by value?
Java is always pass by value. For a primitive the value itself is copied; for a reference type the value of the reference — the address of the object in the heap — is copied.
That has two consequences. A method can change the fields of the object it received: the copied reference points at the very same heap object, so the change is visible to the caller. But a method cannot make the caller's variable point to a different object: an assignment like point = new Point() inside the method only overwrites the local copy of the reference in its own stack frame.
4. Why are local variables thread-safe while objects in the heap are not?
Why are local variables thread-safe while objects in the heap are not?
Every thread gets its own stack. The local variables of a method live in a frame of that thread's stack and are by definition invisible to other threads, which makes them thread-safe without any synchronization.
There is one heap per JVM and it is shared by all threads. An object created in one thread can be read and modified from another one as soon as a reference to it is passed there — which is why shared objects have to be protected with synchronized, volatile or other synchronization tools.
At the same time an object in the heap is not "visible everywhere" by itself: it can only be reached through a chain of references. If no reference was passed anywhere and the last one goes out of scope, the object becomes unreachable and will be collected by the garbage collector.
5. When do StackOverflowError and OutOfMemoryError: Java heap space occur?
When do StackOverflowError and OutOfMemoryError: Java heap space occur?
StackOverflowError is thrown when a thread runs out of stack space. The usual cause is recursion without a base case: every call pushes another frame until the stack is full. The per-thread stack size is set with -Xss.
OutOfMemoryError: Java heap space is thrown when there is no room left in the heap for a new object and the garbage collector cannot free anything. The classic scenario is a memory leak: a collection keeps growing and holds references to objects, so they stay reachable. Heap size is configured with -Xms (initial) and -Xmx (maximum), while Metaspace is capped with -XX:MaxMetaspaceSize.