What is a StackOverflowError
, what causes it, and how should I deal with them?
What is a StackOverflowError? Originally Answered: What is a Stack OverflowError in Java? When we fill a bucket with water which exceeds its volume, you can see an overflow of water from the bucket.
Some of the most common causes for a java.lang.StackOverflowError are: Deep or infinite recursion - If a method calls itself recursively without a terminating condition. Cyclic relationships between classes - If a class A instantiates an object of class B, which in turn instantiates an object of class A.
Stack overflow means exactly that: a stack overflows. Usually there's a one stack in the program that contains local-scope variables -> No, every thread has its own stack which contains stack frames for every method invocation that contains local variables..
An example of throwing a StackOverflowError is shown below: public class StackOverflowErrorExample { public static void recursivePrint (int num) { System.out.println ("Number: " + num); if (num == 0) return; else recursivePrint (++num); } public static void main (String [] args) { StackOverflowErrorExample.recursivePrint (1); } }
Parameters and local variables are allocated on the stack (with reference types, the object lives on the heap and a variable in the stack references that object on the heap). The stack typically lives at the upper end of your address space and as it is used up it heads towards the bottom of the address space (i.e. towards zero).
Your process also has a heap, which lives at the bottom end of your process. As you allocate memory, this heap can grow towards the upper end of your address space. As you can see, there is a potential for the heap to "collide" with the stack (a bit like tectonic plates!!!).
The common cause for a stack overflow is a bad recursive call. Typically, this is caused when your recursive functions doesn't have the correct termination condition, so it ends up calling itself forever. Or when the termination condition is fine, it can be caused by requiring too many recursive calls before fulfilling it.
However, with GUI programming, it's possible to generate indirect recursion. For example, your app may be handling paint messages, and, whilst processing them, it may call a function that causes the system to send another paint message. Here you've not explicitly called yourself, but the OS/VM has done it for you.
To deal with them, you'll need to examine your code. If you've got functions that call themselves then check that you've got a terminating condition. If you have, then check that when calling the function you have at least modified one of the arguments, otherwise there'll be no visible change for the recursively called function and the terminating condition is useless. Also mind that your stack space can run out of memory before reaching a valid terminating condition, thus make sure your method can handle input values requiring more recursive calls.
If you've got no obvious recursive functions then check to see if you're calling any library functions that indirectly will cause your function to be called (like the implicit case above).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With