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.