Skip to content
Exception in thread 'main' java.lang.StackOverflowError

Exception in thread 'main' java.lang.StackOverflowError

DodaTech 3 min read

StackOverflowError fires when a thread’s call stack exceeds its max depth. Each method call uses stack space — runaway recursion fills it up and crashes the JVM.

What It Means

The JVM allocates a fixed-size stack per thread (typically 1 MB on most systems). Every method invocation consumes stack space for local variables, parameters, and return addresses. When the stack can’t grow any larger, the JVM throws StackOverflowError.

Why It Happens

  • Recursive method has no base case (termination condition).
  • The base case is never reached because input doesn’t converge.
  • Accidental mutual recursion (method A calls B, B calls A).
  • Deep call chains in complex frameworks (rare).
  • Too many local variables in a single method on a small stack.

How to Fix It

1. Add a proper base case to recursion

// BUG: no base case — infinite recursion
public int factorial(int n) {
    return n * factorial(n - 1);  // never stops
}

// FIX: add base case
public int factorial(int n) {
    if (n <= 1) return 1;         // base case
    return n * factorial(n - 1);  // recursive case
}

2. Verify the input converges toward the base case

// BUG: doesn't converge for negative input
public int sum(int n) {
    if (n == 0) return 0;        // base case
    return n + sum(n - 1);       // n goes: 5,4,3,2,1,0,-1,-2...
}

// FIX: guard against negative input
public int sum(int n) {
    if (n <= 0) return 0;
    return n + sum(n - 1);
}

3. Convert recursion to iteration

// Recursive — risk of overflow for large n
public long factorial(int n) {
    if (n <= 1) return 1;
    return n * factorial(n - 1);
}

// Iterative — no stack growth
public long factorial(int n) {
    long result = 1;
    for (int i = 2; i <= n; i++) {
        result *= i;
    }
    return result;
}

4. Increase the stack size (when deep recursion is intentional)

# Increase stack size to 2 MB per thread
java -Xss2m com.example.Main

This is a workaround, not a real fix. Use it when you have a legitimate need for deep recursion (e.g., traversing a deeply nested tree structure).

5. Enable stack trace to find the repeating cycle

java -XX:+StackTraceInThrowable com.example.Main

Look at the stack trace — if the same sequence of methods repeats, you’ve found the infinite cycle.

How large is the default stack size?
It varies by JVM and platform. On modern 64-bit Linux it’s typically 1 MB. On Windows it’s 320 KB or 1 MB depending on the JVM version. Check with java -XX:+PrintFlagsFinal | grep ThreadStackSize.
Can StackOverflowError occur without recursion?
Yes, but it’s extremely rare. You’d need an extraordinarily deep call chain of non-recursive methods, hundreds of thousands of levels deep. In practice, nearly all StackOverflowErrors are caused by infinite or unbounded recursion.
Does tail-call optimization exist in Java?
No. The JVM does not perform tail-call optimization (TCO). Even if your recursive call is in tail position, it still consumes stack space. Languages like Scala that run on the JVM can sometimes optimize this, but plain Java cannot.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro