Home » Java » What is a StackOverflowError?

What is a StackOverflowError?

Posted by: admin November 2, 2017 Leave a comment

Questions:

What is a StackOverflowError, what causes it, and how should I deal with them?

Answers:

Parameters and local variables are allocated on the stack (with reference types the object lives on the heap and a variable references that object). 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. 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 than 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.

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).

Questions:
Answers:

If you have a function like:

int foo()
{
    // more stuff
    foo();
}

Then foo() will keep calling itself, getting deeper and deeper, and when the space used to keep track of what functions you’re in is filled up, you get the stack overflow error.

Questions:
Answers:

To describe this, first Let us understand how local variable and object are stored,
Local variable are stored in stack
enter image description here

if you look at the image you should be able to understand how things are working.

When a function call is invoked by a Java application, a stack frame is allocated on the call stack. The stack frame contains the parameters of the invoked method, its local parameters, and the return address of the method. The return address denotes the execution point from which, the program execution shall continue after the invoked method returns. If there is no space for a new stack frame then, the StackOverflowError is thrown by the Java Virtual Machine (JVM).
The most common case that can possibly exhaust a Java application’s stack is recursion. In recursion, a method invokes itself during its execution. Recursion is considered as a powerful general-purpose programming technique, but must be used with caution, in order for the StackOverflowError to be avoided.
An example that throws a StackOverflowError is shown below:

StackOverflowErrorExample.java:

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);
    }
}

In this example, we define a recursive method, called recursivePrint that prints an integer and then, calls itself, with the next successive integer as an argument. The recursion ends once we invoke the method, passing 0 as a parameter. However, in our example, we start printing numbers from 1 and thus, the recursion will never terminate.
A sample execution, using the -Xss1M flag that specifies the size of the thread stack to equal to 1MB, is shown below:

Number: 1
Number: 2
Number: 3
...
Number: 6262
Number: 6263
Number: 6264
Number: 6265
Number: 6266
Exception in thread "main" java.lang.StackOverflowError
        at java.io.PrintStream.write(PrintStream.java:480)
        at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
        at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
        at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:104)
        at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:185)
        at java.io.PrintStream.write(PrintStream.java:527)
        at java.io.PrintStream.print(PrintStream.java:669)
        at java.io.PrintStream.println(PrintStream.java:806)
        at StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:4)
        at StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:9)
        at StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:9)
        at StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:9)
        ...

Depending on the JVM’s initial configuration, the results may differ, but eventually the StackOverflowError shall be thrown. This example is a very good example of how recursion can cause problems, if not implemented with caution.

How to deal with the StackOverflowError

  1. The simplest solution is to carefully inspect the stack trace and
    detect the repeating pattern of line numbers. These line numbers
    indicate the code being recursively called. Once you detect these
    lines, you must carefully inspect your code and understand why the
    recursion never terminates.

  2. If you have verified that the recursion
    is implemented correctly, you can increase the stack’s size, in
    order to allow a larger number of invocations. Depending on the Java
    Virtual Machine (JVM) installed, the default thread stack size may
    equal to either 512KB, or 1MB. You can increase the thread stack
    size using the -Xss flag. This flag can be specified either via the
    project’s configuration, or via the command line. The format of the
    -Xss argument is:
    -Xss[g|G|m|M|k|K]

Questions:
Answers:

Stack overflow means exactly that: a stack overflows. Usually there’s a one stack in the program that contains local-scope variables and addresses where to return when execution of a routine ends. That stack tends to be a fixed memory range somewhere in the memory, therefore it’s limited how much it can contain values.

If the stack is empty you can’t pop, if you do you’ll get stack underflow error.

If the stack is full you can’t push, if you do you’ll get stack overflow error.

So stack overflow appears where you allocate too much into the stack. For instance, in the mentioned recursion.

Some implementations optimize out some forms of recursions. Tail recursion in particular. Tail recursive routines are form of routines where the recursive call appears as a final thing what the routine does. Such routine call gets simply reduced into a jump.

Some implementations go so far as implement their own stacks for recursion, therefore they allow the recursion to continue until the system runs out of memory.

Easiest thing you could try would be to increase your stack size if you can. If you can’t do that though, the second best thing would be to look whether there’s something that clearly causes the stack overflow. Try it by printing something before and after the call into routine. This helps you to find out the failing routine.

Questions:
Answers:

A stack overflow is usually called by nesting function calls too deeply (especially easy when using recursion, i.e. a function that calls itself) or allocating a large amount of memory on the stack where using the heap would be more appropriate.

Questions:
Answers:

Like you say, you need to show some code. 🙂

A stack overflow error usually happens when your function calls nest too deeply. See the Stack Overflow Code Golf thread for some examples of how this happens (though in the case of that question, the answers intentionally cause stack overflow).

Questions:
Answers:

The most common cause of stack overflows is excessively deep or infinite recursion. If this is your problem, this tutorial about Java Recursion could help understand the problem.

Questions:
Answers:

Following would give StackOverflowError:

class  StackOverflowDemo
{
    public static void badRecursiveCall() {
     badRecursiveCall();
    }

    public static void main(String[] args) 
    {
        badRecursiveCall();
    }
}

Questions:
Answers:

Here is an example of a recursive algorithm for reversing a singly linked list. On a laptop with the following spec (4G memory, Intel Core i5 2.3GHz CPU, 64 bit Windows 7), this function will run into StackOverflow error for a linked list of size close to 10,000.

My point is that we should use recursion judiciously, always taking into account of the scale of the system.
Often recursion can be converted to iterative program, which scales better. (One iterative version of the same algorithm is given at the bottom of the page, it reverses a singly linked list of size 1 million in 9 milliseconds.)

    private static LinkedListNode doReverseRecursively(LinkedListNode x, LinkedListNode first){

    LinkedListNode second = first.next;

    first.next = x;

    if(second != null){
        return doReverseRecursively(first, second);
    }else{
        return first;
    }
}

public static LinkedListNode reverseRecursively(LinkedListNode head){
    return doReverseRecursively(null, head);
}

Iterative Version of the Same Algorithm:

    public static LinkedListNode reverseIteratively(LinkedListNode head){
    return doReverseIteratively(null, head);
}   

private static LinkedListNode doReverseIteratively(LinkedListNode x, LinkedListNode first) {

    while (first != null) {
        LinkedListNode second = first.next;
        first.next = x;
        x = first;

        if (second == null) {
            break;
        } else {
            first = second;
        }
    }
    return first;
}


public static LinkedListNode reverseIteratively(LinkedListNode head){
    return doReverseIteratively(null, head);
}

Questions:
Answers:

The term “stack overrun (overflow)” is often used but a misnomer; attacks do not overflow the stack but buffers on the stack.

Questions:
Answers:

StackOverflowError in a runtime error in java. It is thrown when an application recurses too deeply. Whenever the method execution happens a call stack with limited amount of memory location is assigned. This amount of memory is allocated by JVM. Based upon the number of the method execution the size of the call stack grows and srinks.

In most of the cases StackOverError is thrown when call stack exceeds because of excessive deep or infinite recursion. Durning which the need to store the local variable in the method exceeds the allocated stack size. In such a StackOverFlowError occurs. It is shown in the program below:

public class Factorial {
    public static int factorial(int n){
        if(n == 1){
            return 1;
        }
        else{
            return n * factorial(n-1);
        }
    }

    public static void main(String[] args){
        System.out.println("Main method started");
        int result = Factorial.factorial(-1);
        System.out.println("Factorial ==>"+result);
        System.out.println("Main method ended");
    }
}

Here we had implemented factorial using recursion in java. The code works fine when the positive number is passed as argument to “factorial” method. But the problem occurs when the we provide negative number as argument. In such a case the recursion will never go to the exit condition resulting in stack overflow and it will throw this exception.

Main method started
Exception in thread "main" java.lang.StackOverflowError
at com.program.stackoverflow.Factorial.factorial(Factorial.java:9)
at com.program.stackoverflow.Factorial.factorial(Factorial.java:9)
at com.program.stackoverflow.Factorial.factorial(Factorial.java:9)

In the above case it can be avoided doing programmatic changes.
But if the program logic it correct and still it occurs then you stack size needs to be increase

You can increase the stack size by using -Xss4m.

Questions:
Answers:

Here’s an example

public static void main(String[] args) {
    System.out.println(add5(1));
}

public static int add5(int a) {
    return add5(a) + 5;
}

A StackOverflowError basically is when you try to do something, that most likely calls itself, and goes on for infinity (or until it gives a StackOverflowError).

add5(a) will call itself, and then call itself again, and so on.