DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workkloads.

Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Java Virtual Threads and Scaling
  • Java’s Next Act: Native Speed for a Cloud-Native World
  • The Energy Efficiency of JVMs and the Role of GraalVM
  • Understanding Root Causes of Out of Memory (OOM) Issues in Java Containers

Trending

  • Fixing Common Oracle Database Problems
  • Teradata Performance and Skew Prevention Tips
  • Scaling Mobile App Performance: How We Cut Screen Load Time From 8s to 2s
  • Analyzing “java.lang.OutOfMemoryError: Failed to create a thread” Error
  1. DZone
  2. Coding
  3. Java
  4. StackOverFlow Error: Causes and Solutions

StackOverFlow Error: Causes and Solutions

Want to learn more about the potential causes and solutions to the StackOverFlowError in your JVM project? Check out this post to learn more.

By 
Ram Lakshmanan user avatar
Ram Lakshmanan
DZone Core CORE ·
Updated Oct. 18, 18 · Presentation
Likes (9)
Comment
Save
Tweet
Share
96.7K Views

Join the DZone community and get the full member experience.

Join For Free

StackOverFlowError is one of the commonly confronted JVM errors. In this blog post, we will look at the inner mechanics of thread stacks, the reasons that can trigger StackOverFlowError, and potential solutions to address this error.

To gain a deeper understanding of StackOverFlowError, let’s review this simple program:

public class SimpleExample {

      public static void main(String args[]) {

            a()
      }

      public static void a() {

            int x = 0;
            b();
      }

      public static void b() {

            Car y = new Car();
            c();
      }

      public static void c() {

            float z = 0f;
      System.out.println("Hello");
      }
}


This program is very simple with the following execution code:

  1.  main() method is invoked first
  2.  main() method invokes a()  method. Inside a() method, the integer variable ‘x’ is initialized to value 0.
  3.  a() method in turn invokes b() method. Inside b() method, the Car object is constructed and assigned to variable ‘y.'
  4.  b() method in turn invokes the c() method. Inside the c() method, the float variable ‘z’ is initialized to value 0.

Now, let’s review what happens behind the scenes when the above simple program is executed. Each thread in the application has its own stack. Each stack has multiple stack frames. The thread adds the methods it’s executing, primitive data types, object pointers, and return values to its stack frame in the sequence order in which they are executed.

thread-stack-frame-1

Fig 1: Thread’s Stack frame

Step #1: main() method is pushed into the application thread’s stack.

Step #2: a() method is pushed into the application thread’s stack. In a() method, primitive data type ‘int’ is defined with value 0 and assigned to variable x. This information is also pushed into the same stack frame. Note that both data, i.e., ‘0’ and variable ‘x,' is pushed into the thread’s stack frame.

Step #3: b() method is pushed into the thread’s stack. In the b() method, the Car object is created and assigned to variable ‘y.' A crucial point to note here is that the ‘Car’ object is created in the heap and not in the thread’s stack. Only the Car object’s reference, i.e., y, is stored in the thread’s stack frame.

Step #4: c() method is pushed into the thread’s stack. In c() method, primitive data type ‘float’ is defined with value 0f and assigned to variable z. This information is also pushed into the same stack frame. Note both data, i.e., ‘0f’ and variable ‘z,’ is pushed into the thread’s stack frame.

Once each method’s execution is completed, the method and the variables/object pointers stored in the stack frame are removed, as shown in Fig 2.

thread-stack-frame-2

Fig 2: Thread’s stack frame after executing methods

What Causes StackOverflowError?

As you can see, the thread’s stack stores methods it’s executing, primitive datatypes, variables, object pointers, and return values. All of these consume memory. If the thread’s stack sizes grow beyond the allocated memory limit, then StackOverflowError is thrown. Let’s look at the below buggy program, which will result in a  StackOverflowError:

public class SOFDemo {

         public static void a() {

                  // Buggy line. It will cause method a() to be called infinite number of times.
                  a();
         }

         public static void main(String args[]) {

                   a();
         }
}


In this program, the main() method invokes a()  method. a() method recursively calls itself. This implementation will cause  a() method to be invoked an infinite number of times. In this circumstance, a() method will be added to the thread’s stack frame an infinite number of times. Thus, after a few thousand iterations, the thread’s stack size limit would be exceeded. Once the stack size limit is exceeded, it will result in  StackOverflowError:

Exception in thread "main" java.lang.StackOverflowError
       at com.buggyapp.stackoverflow.SOFDemo.a(SOFDemo.java:7)
       at com.buggyapp.stackoverflow.SOFDemo.a(SOFDemo.java:7)
       at com.buggyapp.stackoverflow.SOFDemo.a(SOFDemo.java:7)
       at com.buggyapp.stackoverflow.SOFDemo.a(SOFDemo.java:7)
       at com.buggyapp.stackoverflow.SOFDemo.a(SOFDemo.java:7)
       at com.buggyapp.stackoverflow.SOFDemo.a(SOFDemo.java:7)
       at com.buggyapp.stackoverflow.SOFDemo.a(SOFDemo.java:7)
       at com.buggyapp.stackoverflow.SOFDemo.a(SOFDemo.java:7)


stackOverflowError

Fig 3: StackOverflowError progression

What Are the Solutions to StackOverflowError?

There are a couple of strategies to address  StackOverflowError.

1. Fix the Code

Because of a non-terminating recursive call (as shown in the above example), thread stack size can grow to a large size. In those circumstances, you must fix the source code that is causing recursive looping. When StackOverflowError is thrown, it will print the stacktrace of the code that it was recursively executing. This code is a good pointer to start debugging and fixing the issue. In the above example, it’s the a()  method.

2. Increase Thread Stack Size (-Xss)

There might be legitimate reasons why a thread's stack size needs to be increased. Maybe the thread has to execute a large number of methods or a lot of local variables/created in the methods the thread has been executing? In such circumstances, you can increase the thread’s stack size using the JVM argument: -Xss. This argument needs to be passed when you start the application. Example:

-Xss2m


This will set the thread’s stack size to 2 mb.

It might bring up a question: What is the default thread’s stack size? Default thread stack size varies based on your operating system, Java version, and vendor.

JVM version

Thread stack size

Sparc 32-bit JVM

512k

Sparc 64-bit JVM

1024k

x86 Solaris/Linux 32-bit JVM

320K

x86 Solaris/Linux 64-bit JVM

1024K

Windows 32-bit JVM

320K

Windows 64-bit JVM

1024K

3. Threads With Custom Stack Size

Another approach to mitigating StackOverflowError is by utilizing Java’s thread constructor, which allows you to specify a custom stack size for individual threads. This constructor can be found in the Java documentation. While this option provides the flexibility to set a specific stack size for each thread, it’s important to note that its effectiveness might vary across different platforms.

Thread thread = new Thread(null, runnable, "CustomThread", customStackSize); 
thread.start();


However, it’s crucial to be aware that the impact of setting the stackSize parameter may not be
consistent across all platforms. The Java documentation states: “On some platforms, the value of the stackSize parameter may have no effect whatsoever. The virtual machine is free to treat the stackSize parameter as a suggestion.”

In our own testing, we found that invoking this constructor with a custom stack size had no effect on platforms such as Windows and certain others. This lack of consistency across platforms makes this option less reliable as a universal solution. As a best practice, it’s advisable to choose solutions that work consistently across all platforms to ensure the stability and reliability of your application.

Additional Reference

java.lang.StackOverflowError – How to solve StackOverflowError  

Java (programming language) Java virtual machine Debug (command)

Opinions expressed by DZone contributors are their own.

Related

  • Java Virtual Threads and Scaling
  • Java’s Next Act: Native Speed for a Cloud-Native World
  • The Energy Efficiency of JVMs and the Role of GraalVM
  • Understanding Root Causes of Out of Memory (OOM) Issues in Java Containers

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!