What is a StackOverflowError in Java?

StackOverFlowError-in-Java.jpg

A StackOverflowError in Java occurs when a thread’s stack, which stores information about the method calls and variables, exceeds its size limit. This typically happens due to uncontrolled recursion, where a method keeps calling itself without stopping. As a result, the stack runs out of space, causing the program to crash. In this blog, we will discuss the StackOverflowError in more detail.

Table of contents:

What is StackOverflowError in Java?

A StackOverflowError occurs when a program runs out of space in the function call stack. The call stack is the place where the program stores all the information about the method calls. Java recursion error usually occurs due to infinite recursion or deep function calls. It indicates that the program has used all the memory limits for the call stack.

How StackOverflowError Occurs in Java?

A stack is a data structure that follows the principle of  Last In, First Out (LIFO), where the last element added will be the first one to be removed. Stacks are commonly used in managing function calls and parsing expressions.

When a method is called in Java, a new stack frame is created for that method on the call stack. This stack frame holds the method’s local variables and parameters.  As methods are called, new stack frames are added to the stack. These stack frames are created iteratively and are terminated when the end of the method call is reached in the nested methods. If the JVM runs out of space during this process, a StackOverflowError will be thrown.

The two most common causes of stack overflow are deep or infinite recursion and cyclic relationships.

Internal Working of StackOverflowError in the JVM

When a stack overflow occurs, the excess data can corrupt other variables, like changing variable values and overwriting the return addresses of the variable. In some cases, this will cause the program to crash. At other times, the program will continue to run, making it more difficult to troubleshoot the problem once the error is discovered. The longer the program runs, the harder this becomes.

A program prone to stack overflows can expose security vulnerabilities that hackers can exploit. By overwriting the call stack, they can insert their executable code, which could have an impact on how the program works or how it is accessed. 

For example, a hacker might be able to use a stack overflow vulnerability to alter a password or delete a file.

Causes of StackOverflowError in Java

A java.lang.StackOverflowError generally occurs when the stack used by an application goes beyond its limit. Here are some common java StackOverflowError causes:

1. Infinite Recursion in Java

This occurs when a method repeatedly calls itself and does not have a base case. In recursive functions, each call adds a new frame to the stack, which holds information about the method call. So, without a stopping condition, the method will keep calling itself, and the stack will fill up, and hence the program will throw a StackOverflowError.

Example:

Java

Output:

1. Infinite recursion in Java

Explanation: In this example, the method infiniteRecursion() keeps calling itself without having a stop condition, which will keep the stack filling up and causing a stack overflow error.

2. Cyclic Relationships Between Methods or Objects

It occurs when two or more classes make the objects of each other in a loop, which results in repeated method calls. 

For example, if Class A creates an object of Class B, and Class B creates an object of Class A.

Example:

Java

Output:

2. Cyclic relationships in Java

Explanation: In the above example, both classes form a cycle where each class keeps trying to create an object of the other. This cycle continues, causing the stack to grow until a java.lang.StackOverflowError occurs.

3. Excessive Stack Memory Usage

These are the applications that use a large amount of memory, which can be due to the large objects or the data structures, like large XML files or images.  

When large objects are created within the method calls, they can use up a lot of stack space. If the stack runs out of memory, it can result in a StackOverflowError or an OutOfMemoryError.

4. Improper Stack Size Configuration

If the stack size is set too small, it may not have enough space for the function calls, which will lead to a StackOverflowError when the program runs out of stack memory.

How to Fix StackOverflowError in Java (With Examples)

There are many ways that a StackOverflowError in Java might arise. As a good developer, you need to know methods to avoid them altogether when writing your source code. Below we have listed down a few methods for you to avoid this error.

1. Add Proper Terminating Conditions

A  base case is important in recursion to stop a function at a particular point, otherwise, it can lead to a StackOverflowError, i.e., A recursive method should call itself until a specific condition is met, and once that condition is met, it should stop calling itself.

Example:

Java

Output:

1. Proper Terminating Condition

Explanation: 

The base case in the factorial method is if (n == 0), which stops the recursion by returning 1. Without the use of the base case, the function will keep calling itself and will lead to a stack overflow error.

Get 100% Hike!

Master Most in Demand Skills Now!

2. Break Cyclic Dependencies

To fix the cyclic Relationships Between the Classes, we can modify the design of the classes in many ways. Some of them are:

a. Use Lazy Initialization: In this method, one should be careful while creating the objects. They are created only when they are needed; do not create them in the constructor. This will break the Java cyclic dependency error of the classes.

Example:

Java

Output:

3. Fixing Cyclic Relationships Between Classes

Explanation: In the above code, lazy initialization is used to break the cyclic dependency between classes A and B. Instead of creating the instances of A and B within their constructors, their reference is set later using the setter method. This makes both the classes to start separately and avoids cyclic creation when the object is created.

b. Dependency Injection (DI): Dependency Injection is a technique where the dependencies (in this case, objects of A and B) are provided to the classes rather than allowing them to create them. This approach loosens the coupling between the classes and prevents the cyclic dependencies between them.

Example:

Java

Output:

Dependency Injection

Explanation: This approach avoids cyclic constructor calls. It respects the DI principle – dependencies are not created inside the class but are supplied externally. Also, it ensures both A and B hold valid references to each other without a stack overflow.

3. Increase Java Stack Size -Xss (When Necessary)

The size of the stack can be increased by size using the –Xss option. If your program has a lot of recursive calls, you need to allocate more memory for the call the stack.

Syntax: 

java -Xss<size> <class_name>

Example: 

Increase the stack size to 2 MB
java -Xss2m MyProgram

where; 

Xss2m: sets the stack size to 2 megabytes.

MyProgram: Replace it with your class name.

Note: Be careful when making the stack size larger, as it can use more memory and can cause performance issues if made too large.

Real-World Examples of StackOverflowError in Java

Understanding real-world scenarios where a java.lang.StackOverflowError occurs can help developers identify and fix similar issues in their projects more quickly. The two common examples are of Spring Boot and Hibernate, where circular dependencies and recursive loading can triggers StackOverflowError in Java.

1. Spring Boot circular dependencies

Let us consider a scenario where in SpringBoot, Bean A depends on Bean B, and Bean B, in turn, depends on Bean A (directly or indirectly); this forms a circular dependency.

During the setup of the application, Spring tries to create and inject these beans, calling constructors recursively. This recursion continues until the JVM call stack is exhausted, resulting in a StackOverflowError.

Example:

Java

Explanation: The above configuration will cause a circular constructor call and eventually throw a StackOverflowError in Java compiler.

2. Hibernate lazy loading loops

Let us consider another scenario involving Hibernate. Hibernate uses lazy loading to fetch related entities only when needed. However, if two entities reference each other and both are configured for lazy loading, accessing one entity can trigger an endless loop of fetching the other.
Due to this, what happens is that each access triggers another fetch and causes many method calls until the stack overflows.

Example:

Java

Explanation: As you can see, if either side tries to access the other in a way that keeps triggering lazy loading, the call stack grows until a StackOverflowError in Java occurs.

While these examples use Spring Boot and Hibernate, similar StackOverflowError situations can happen in any framework or custom code where circular references or uncontrolled recursion exist. Identifying such patterns early can save significant debugging time.

Constructors of StackOverflowError in Java

StackOverflow has two main constructors. These are:

1. StackOverflowError():

  • It is the default constructor of StackOverflowError. It creates an object of the error without any extra information.
  • This constructor is typically invoked when a stack overflow occurs, and it doesn’t carry any extra messages.

Syntax:

public StackOverflowError()

Example:

throw new StackOverflowError();  

2. StackOverflowError(String message):

  • This constructor allows you to provide a message explaining the reason for the stack overflow.
  • You can use this constructor to provide an explanation of the cause of the error.

Syntax:

public StackOverflowError(String s)

Example:

throw new StackOverflowError("Stack overflow due to excessive recursion");  // Custom message

Common Mistakes When Handling StackOverflowError

When you want a Java error handling method to fix a Java stack overflow error, be careful to avoid the following mistakes:

  • Ignoring the infinite recursion can make the problem more complex and difficult to solve, which can cause your program to crash one after the other.
  • Adding more memory to the setup without solving the main issue will not solve the underlying problem and can hide important bugs.
  • Not checking the base case in recursive methods can lead to endless loops and stack overflow errors.
  • Overlooking code reviews might cause you to miss small mistakes that can lead to big problems later.
  • Trying to fix the error without understanding the stack trace can waste a lot of time and make it harder to find the real issue

Troubleshooting StackOverflowError in Java

Here are some easy tips to help you find and fix Java stack overflow errors:

  • Test your code multiple times to check if the problem is fixed.
  • Read the error message very carefully to see where the problem is starting.
  • Check if your code is stopped in a loop or calling itself again and again without stopping.
  • Add print statements in between the code to see what your program is doing, step by step.
  • Make sure your loops or functions have a condition to stop, so they do not run endlessly.
  • Make your code smaller and simpler to find the part that is causing the problem.

Why Understanding StackOverflowError in Java is Important?

  • There are many benefits of understanding the Java Stack Overflow Error in Java, as it helps in the following ways.
  • It helps you fix your code faster. As you can find the problem in your code easily, as it gives you the line of code where the error is present.
  • Understanding this error will help you avoid writing code that causes this error, like not using too much recursion. Hence, it will help you write better code.
  • It saves the time of user, as the number of lines is detected.
  • It helps you understand the Java memory system and how function calls are handled.

StackOverflowError vs OutOfMemoryError

Aspect StackOverflowError (Java) OutOfMemoryError (Java)
Type of Error java.lang.StackOverflowError java.lang.OutOfMemoryError
Cause Excessive method calls (e.g., infinite recursion) that exceed stack size Memory leaks or excessive object creation exceeding heap size
Memory Area Affected Call Stack Heap Memory
Common Triggers Infinite recursion, cyclic constructor calls Large objects, memory leaks, uncollected references
Fix Approach Refactor recursion, add base case, increase stack size (-Xss) Optimize usage, remove unused references, increase heap size (-Xmx)
Error Message Exception in thread "main" java.lang.StackOverflowError Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
Prevention Strategy Avoid deep or infinite recursion, track method calls Use profiling tools, optimize memory footprint

Heap Overflow vs StackOverflowError in Java

In Java, the memory is divided into several areas, one of which is the heap. The heap is a place where objects are allocated dynamically at runtime. A heap overflow in Java is referred to as the OutOfMemoryError, caused due to excessive memory allocation when the heap is full due to large memory allocation or memory leaks.

With heaps, users are responsible for deallocating memory. If they fail to do this properly, heap overflow can occur, resulting in critical data being overwritten. Heap overflow can also occur when the stored variables contain more data than the amount of allocated memory. 

Unlike C or C++, Java uses automatic garbage collection, meaning the programmer doesn’t need to manage memory manually by allocating and freeing it, but poor programming practices such as memory leaks can still lead to heap-related issues.

Best Practices to Prevent StackOverflowError in Java

To fix StackOverflowError Java issues and write safer code, here are the best practices every Java beginner should follow:

  1. Use Proper Base Cases in Recursion
    • Every recursive method should include a clear and reachable termination condition.
    • Prevents Java infinite recursion error and ensures the function exits correctly.
  2. Avoid Cyclic Constructor Calls
    • Refactor classes to eliminate Java cyclic dependency errors. Use lazy initialization or dependency injection to break circular object creation.
  3. Increase Stack Size for Deep Recursion (if needed)
    • Use the JVM option -Xss (e.g., java -Xss2m ClassName) only when justified.
    • Useful when recursion depth is valid but large (e.g., in parsing or tree algorithms).
  4. Refactor Deep Recursion into Iteration
    • Replace deep recursive logic with iterative logic when possible.
    • Helps prevent Java stack overflow and is easier to debug and test.
  5. Enable Stack Traces and Logging
    • When debugging a stack overflow in Java, log method entry points and call chains to locate the recursive loop quickly.
    • Analyze the stack trace to pinpoint where the Java recursion error starts.

Following these tips can significantly reduce the risk of encountering a StackOverflowError Java issue in production systems.

Online Java Certification Course Free
This free Java course with certification will give you a kickstart in your journey towards learning Java
quiz-icon

Useful Resources:

Conclusion

In the end, we learned that a StackOverflowError in Java occurs when the stack has no memory. Java infinite recursion error can be caused by infinite recursion, cyclic dependencies, or high memory usage. To correct this, you can use a proper base condition in recursion, address cyclic relationships, and optimize the use of memory. You can also change the stack size, as per your needs. 

Master Java fundamentals with our hands-on course and sharpen your skills with curated interview questions. Start learning today to boost your coding confidence and ace your next Java interview.

What is a StackOverflowError in Java – FAQs

Q1. Why am I getting a StackOverflowError in Java?

A StackOverflowError in Java occurs when the JVM stack runs out of memory. This usually happens due to infinite recursion, excessive recursion depth, or a circular instantiation that keeps creating stack frames until the memory limit is reached.

Q2. What is the main java StackOverflowError cause?

The most common causes are, a recursive method without a base case (infinite recursion), StackOverflowError constructor recursion, where objects keep creating each other in their constructors and deep method call chains in frameworks, such as Hibernate lazy loading loops or Spring Boot circular dependencies.

Q3. How do I fix StackOverflowError in Java?

The best way to prevent a stack overflow is to avoid recursion and use iteration as far as possible.

Q4. What is -Xss in JVM?

-Xss is a JVM parameter that defines the stack size for each thread. A larger stack allows for deeper recursion but uses more memory.

Q5. How to check if a stack is empty or not in Java?

The empty() method in Java is used to check whether a stack is empty or not.

Q6. How to detect infinite recursion in Java?

Detect infinite recursion by ensuring a proper base case and optionally tracking recursion depth or visited states to prevent cycles.

Q7. Can we increase stack size in Java?

Yes, use the -Xss JVM option to increase thread stack size, e.g., java -Xss2m sets it to 2MB.

Q8. What is the difference between StackOverflowError and OutOfMemoryError?

StackOverflowError occurs when the call stack exceeds its limit (often due to deep or infinite recursion), while OutOfMemoryError happens when the heap runs out of memory for new objects.

Q9. How to resolve stack overflow in recursion?

Resolve stack overflow by fixing or adding a base case, converting recursion to iteration, or increasing stack size if recursion is necessary.

Q10. What is -Xss in Java JVM?

-Xss sets the stack size per thread in the JVM; it controls how deep recursion can go before a StackOverflowError occurs.

About the Author

Technical Research Analyst - Full Stack Development

Kislay is a Technical Research Analyst and Full Stack Developer with expertise in crafting Mobile applications from inception to deployment. Proficient in Android development, IOS development, HTML, CSS, JavaScript, React, Angular, MySQL, and MongoDB, he’s committed to enhancing user experiences through intuitive websites and advanced mobile applications.

Full Stack Developer Course Banner