StackOverflowError in Java

In this article, we will learn what is StackOverflowError in Java, its common causes, examples, and solutions.

What is StackOverflowError? 

The StackOverflowError is a runtime error in Java. It's thrown when the depth of the stack of a program goes beyond a certain limit, typically due to excessive recursion. Each time a method is called, a frame is pushed onto the stack. If these frames accumulate beyond the limit of the stack's depth, a StackOverflowError is thrown.

Common Causes

Uncontrolled Recursion: The most prevalent cause is where a method keeps invoking itself, resulting in infinite recursion. 

Deeply Nested Method Calls: Not as frequent, but a series of long method calls can fill the stack.

Cyclic Dependencies: Two or more classes inter-dependent on each other can cause a loop of repeated method calls, leading to this error. 

Large Stack Allocations: Rare, but allocating large amounts of data on the stack, rather than the heap, can result in this error. 

Examples 

1. Uncontrolled Recursion 

This code snippet shows a method endlessly calling itself:

public class RecursiveDemo {
    public static void recurseForever() {
        recurseForever();
    }

    public static void main(String[] args) {
        recurseForever();
    }
}

Output:

Exception in thread "main" java.lang.StackOverflowError
	at com.javaguides.net.RecursiveDemo.recurseForever(RecursiveDemo.java:5)
	at com.javaguides.net.RecursiveDemo.recurseForever(RecursiveDemo.java:5)
        ...

2. Deeply Nested Method Calls 

Here's a chain of long method calls:

public class DeeplyNestedDemo {
    
    public static void method1() { method2(); }
    public static void method2() { method3(); }
    // ... many such methods ...

    public static void lastMethod() { method1(); }

    public static void main(String[] args) {
        method1();
    }
}

Output:

Exception in thread "main" java.lang.StackOverflowError

3. Cyclic Dependency 

A clear example of two classes inter-dependent on each other:

public class ClassA {
    private ClassB bInstance = new ClassB();

    public void callB() {
        bInstance.methodInB();
    }
}

public class ClassB {
    private ClassA aInstance = new ClassA();

    public void methodInB() {
        aInstance.callB();
    }

    public static void main(String[] args) {
        ClassA a = new ClassA();
        a.callB();
    }
}

Output:

Exception in thread "main" java.lang.StackOverflowError

Solutions 

Spot the Recursion: Check the stack trace. Repeated methods signal uncontrolled recursion. 

Refactor: Check if you can turn a recursive solution into an iterative one. 

Increase the Stack Size: Using the JVM -Xss option, you can increase the stack size, e.g., -Xss1024k. 

Tail Recursion: Though Java doesn't natively optimize it, understanding tail recursion can help in some scenarios. 

Break Cyclic Dependencies: Using design patterns like Dependency Injection or re-evaluating design to separate concerns can help.

Related Exceptions Posts

Java built-in checked exceptions:
Java built-in unchecked exceptions:
Java built-in errors:

Comments