118

How deep do I need to go into the call stack before I get a StackOverflowError? Is the answer platform dependent?

Andrzej Doyle
  • 102,507
  • 33
  • 189
  • 228
ripper234
  • 222,824
  • 274
  • 634
  • 905
  • 1
    Closely related: http://stackoverflow.com/questions/794227/how-to-know-about-outofmemory-or-stackoverflow-errors-ahead-of-time – finnw Jan 19 '11 at 10:35
  • Since this is a good question, I've updated the title to something I feel is more clearly associated with the meaning. (Previously I thought you might be referring to the depth of a *particular* stack you'd captured at runtime, for example). Feel free to change it back if you disagree. – Andrzej Doyle Jan 19 '11 at 11:28

5 Answers5

66

It depends on the amount of virtual memory allocated to the stack.

http://www.odi.ch/weblog/posting.php?posting=411

You can tune this with the -Xss VM parameter or with the Thread(ThreadGroup, Runnable, String, long) constructor.

finnw
  • 47,861
  • 24
  • 143
  • 221
32

I tested on my system and didn't find any constant value, sometimes stack overflow occurs after 8900 calls, sometimes only after 7700, random numbers.

public class MainClass {

    private static long depth=0L;

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

    private static void deep(){
        System.err.println(++depth);
        deep();
    }

}
soufrk
  • 825
  • 1
  • 10
  • 24
troy
  • 704
  • 8
  • 16
  • 18
    Isn't it the case that this is tail recursive and shouldn't ever overflow? Edit: Sorry. In Java it crashed at 8027; in Scala it got up to 8594755 before I got bored. – arya Feb 15 '15 at 02:47
  • 11
    @arya an important part of the JVM semantics is that tail recursion is not supported. This gives a lot of interesting problems for those who want to implement languages with tail recursion on the JVM. – Thorbjørn Ravn Andersen Feb 20 '15 at 23:57
  • 2
    `public foo() { try { foo(); } finally { foo(); } }` can run 'virtually' forever, in java only though. – Felype Mar 23 '15 at 16:45
  • for me, `StackOverflowError` occurs after after 8792 – ericdemo07 Dec 05 '16 at 07:11
  • 3
    @ThorbjørnRavnAndersen tail recursion **optimisation** is not supported. Rather obviously you can have tail recursion. It just doesn't optimise it to not grow the call stack. – slim Aug 16 '17 at 14:48
  • @slim Of course, or it wouldn't be interesting. Feel free to write a full answer explaining this in detail. – Thorbjørn Ravn Andersen Aug 16 '17 at 14:53
20

The stack size can be set with the -Xss command line switch but as a rule of thumb, it is deep enough, hundreds if not thousands of calls deep. (The default is platform dependent, but at least 256k in most platforms.)

If you get a stack overflow, 99% of the time it's caused by an error in the code.

biziclop
  • 48,926
  • 12
  • 77
  • 104
3

Compare these two calls:
(1) Static method:

public static void main(String[] args) {
    int i = 14400; 
    while(true){   
        int myResult = testRecursion(i);
        System.out.println(myResult);
        i++;
    }
}

public static int testRecursion(int number) {
    if (number == 1) {
        return 1;
    } else {
        int result = 1 + testRecursion(number - 1);
        return result;
    }    
}
 //Exception in thread "main" java.lang.StackOverflowError after 62844

(2) Non-static method using a different class:

public static void main(String[] args) {
    int i = 14400;
    while(true){       
        TestRecursion tr = new TestRecursion ();
        int myResult = tr.testRecursion(i);
        System.out.println(myResult);
        i++;
    }
} 
//Exception in thread "main" java.lang.StackOverflowError after 14002

Test recursion class has public int testRecursion(int number) { as the only method.

soufrk
  • 825
  • 1
  • 10
  • 24
sixtytrees
  • 1,156
  • 1
  • 10
  • 25
0

While traversing a tree with huge depth, we could face this


/**
 * -Xss10M
 * max call stack count 92766
 * -Xss100M
 * max call stack count 2148286
 */
public class MaxCallStack {
    private Integer stackCount = 0;

    public static void main(String[] args) {
        MaxCallStack maxStack = new MaxCallStack();
        maxStack.evaluate();
    }

    private void evaluate() {
        try {
            Tree tree = new Tree();
            tree.left = tree;
            traverse(tree);
        } catch (StackOverflowError e) {
            System.out.println(String.format("max call stack count %s", stackCount));
        }
    }

    private void traverse(Tree tree) {
        stackCount++;
        if (tree.left != null) {
            traverse(tree.left);
        }
        if (tree.right != null) {
            traverse(tree.right);
        }
    }

    private class Tree {
        Tree left;
        Tree right;
    }
}

Mukundhan
  • 3,284
  • 23
  • 36