How does StackOverflowError differ from OutOfMemoryError, and how do you tell which one you are facing?
answer
- Both extend VirtualMachineError/Error
- Stack = one thread's frames (-Xss); heap/metaspace = OOM (-Xmx)
- SOE trace: same method repeating
- OOM message names the region
- Opposite fixes: recursion vs leak/retention
basics
~10 sStackOverflowError means one thread ran out of stack space, usually from deep recursion. OutOfMemoryError means the heap (or metaspace) is full, usually from too many or too-large objects. Different memory areas, different causes.
solid answer
~50 sBoth are subclasses of Error (under VirtualMachineError), but they concern different memory regions. StackOverflowError is thrown when a single thread's call stack is exhausted — each method call pushes a frame, and unbounded or very deep recursion overflows the fixed per-thread stack sized by -Xss. OutOfMemoryError is thrown when the JVM cannot allocate more memory in a managed pool: typically the heap (too many live objects, a leak), but also metaspace (class metadata), or 'unable to create native thread' (OS thread limits). You tell them apart from the message and stack trace: a StackOverflowError trace shows the same method or a small cycle repeating thousands of times; an OutOfMemoryError names the exhausted region ('Java heap space', 'Metaspace', 'GC overhead limit exceeded'). Fixes differ too: StackOverflowError is fixed by correcting recursion or switching to iteration; heap OOM by fixing leaks, reducing retention, or raising -Xmx.
go deeper
Knows StackOverflowError = stack, OutOfMemoryError = heap, and they are different problems.
Distinguishes the regions, reads the trace/message to identify which, and names -Xss vs -Xmx as the relevant flags.
Enumerates OOM flavours (heap/metaspace/native thread/GC overhead), explains opposite fixes, and the -Xss vs thread-count tension.
Designs memory budgets across threads and pools, sets heap-dump/diagnostic policy, and reasons about classloader/native-thread limits at production scale.
## The shared parent Both `StackOverflowError` and `OutOfMemoryError` extend `java.lang.VirtualMachineError`, which extends `Error`. So both are **Errors**, not Exceptions: they signal serious JVM-level resource exhaustion that you normally fix at the source rather than catch and continue. But they describe **different memory regions** and have **different causes and fixes**. ## JVM memory regions (the background you need) - **Heap** — where objects created with `new` live; shared by all threads; sized with `-Xms` (initial) and `-Xmx` (max); reclaimed by the garbage collector (GC). - **Metaspace** — native memory holding class metadata (the structure of loaded classes); sized with `-XX:MaxMetaspaceSize`. - **Thread stacks** — each **thread** has its own fixed-size stack of **frames** (one per active method call); sized with `-Xss`. This is **not** the heap. ## StackOverflowError Thrown when a thread tries to push a new stack frame but its stack is full. Cause: almost always **unbounded recursion** (missing base case, mutual recursion, accidental self-call) or **legitimately very deep** recursion, or unusually **large frames**. It affects **one thread's stack** only. Signature in the trace: the **same method (or a short cycle) repeating** over and over — that repetition is the giveaway. Fix: correct the base case, or **convert recursion to iteration** so depth lives on the heap, not the stack; `-Xss` can give a little headroom but cannot cure infinite recursion. ## OutOfMemoryError Thrown when the JVM cannot allocate within a managed pool. It comes in flavours identified by the message: - **`Java heap space`** — the heap is full of **live** (reachable) objects; commonly a **memory leak** (objects kept reachable forever, e.g. an ever-growing cache or static collection) or simply a heap too small for the workload. Fix: find and break the retention (heap dump + analyzer), reduce footprint, or raise `-Xmx`. - **`GC overhead limit exceeded`** — the GC is running almost constantly but reclaiming almost nothing; effectively a near-full heap. - **`Metaspace`** — too much class metadata, often from **classloader leaks** (e.g. repeated redeploys retaining old classloaders). Fix: raise `-XX:MaxMetaspaceSize` or fix the leak. - **`unable to create native thread`** — the OS won't grant more threads; ironically often relieved by a **smaller** `-Xss` (each thread reserves less) or fewer threads. ## How to tell them apart in practice 1. **Read the message line.** `java.lang.StackOverflowError` vs `java.lang.OutOfMemoryError: <region>` is immediate. 2. **Read the trace shape.** StackOverflow: the same frames repeating to enormous depth. OOM: a normal-depth trace at the allocation site, plus the named region. 3. **Look at the fix you'd reach for.** Recursion bug → StackOverflow. Leak / retention / undersized heap → OOM. ## Why the distinction matters They point at **opposite remedies**. Raising `-Xmx` (heap) does nothing for a recursion bug; raising `-Xss` (stack) does nothing for a heap leak — and on a thread-starved system, raising `-Xss` can make 'unable to create native thread' *worse*. Misdiagnosing wastes effort and can hide the real defect.
- Why might lowering -Xss actually help an 'unable to create native thread' OutOfMemoryError?Each thread reserves stack memory equal to -Xss. With many threads, large stacks consume the address space/native memory the OS needs to create more threads. A smaller -Xss lets each thread reserve less, so more threads fit.
- Can catching OutOfMemoryError or StackOverflowError be a good idea?Rarely. Both are Errors signalling exhaustion; the thread/JVM state is suspect afterward. Some servers catch them at request boundaries to fail one request gracefully, but the real fix is to remove the cause (recursion bug, leak, sizing).
saying these in an interview costs you the question
- Treating them as interchangeable
- Raising -Xmx to fix a StackOverflowError (wrong region)
- Assuming OutOfMemoryError is always a leak — it can be an undersized heap or metaspace/native-thread limit
- Thinking either is a checked Exception you should routinely catch