What actually causes a Stack Overflow error? [duplicate]
I've looked everywhere and can't find a solid answer. According to the documentation, Java throws a java.lang.StackOverflowError error under the following circumstance:
Thrown when a stack overflow occurs because an application recurses too deeply.
But this raises two questions:
- Aren't there other ways for a stack overflow to occur, not only through recursion?
- Does the StackOverflowError happen before the JVM actually overflows the stack or after?
To elaborate on the second question:
When Java throws the StackOverflowError, can you safely assume that the stack did not write into the heap? If you shrink the size of the stack or heap in a try/catch on a function that throws a stack overflow, can you continue working? Is this documented anywhere?
Answers I am not looking for:
- A StackOverflow happens because of bad recursion.
- A StackOverflow happens when the heap meets the stack.
Solution 1:
It seems you're thinking that a stackoverflow error is like a buffer overflow exception in native programs, when there is a risk of writing into memory that had not been allocated for the buffer, and thus to corrupt some other memory locations. It's not the case at all.
JVM has a given memory allocated for each stack of each thread, and if an attempt to call a method happens to fill this memory, JVM throws an error. Just like it would do if you were trying to write at index N of an array of length N. No memory corruption can happen. The stack can not write into the heap.
A StackOverflowError is to the stack what an OutOfMemoryError is to the heap: it simply signals that there is no more memory available.
Description from Virtual Machine Errors (§6.3)
StackOverflowError: The Java Virtual Machine implementation has run out of stack space for a thread, typically because the thread is doing an unbounded number of recursive invocations as a result of a fault in the executing program.
Solution 2:
Aren't there other ways for a stack overflow to occur, not only through recursion?
Sure. Just keep calling methods, without ever returning. You'll need a lot of methods, though, unless you allow recursion. Actually, it doesn't make a difference: a stack frame is a stack frame, whether it is one of a recursive method or not is the same.
The answer to your second question is: The stackoverflow is detected when the JVM tries to allocate the stack frame for the next call, and finds it is not possible. So, nothing will be overwritten.