Qual é a profundidade máxima da pilha de chamadas java?


100

Quão profundo eu preciso ir na pilha de chamadas antes de obter um StackOverflowError? A resposta da plataforma depende?


1
Intimamente relacionado: stackoverflow.com/questions/794227/…
finnw

Como essa é uma boa pergunta, atualizei o título para algo que sinto que está mais claramente associado ao significado. (Anteriormente, pensei que você poderia estar se referindo à profundidade de uma pilha específica que você capturou em tempo de execução, por exemplo). Sinta-se à vontade para alterá-lo novamente se você discordar.
Andrzej Doyle

Respostas:



31

Eu testei em meu sistema e não encontrei nenhum valor constante, às vezes o estouro da pilha ocorre após 8.900 chamadas, às vezes somente após 7700, números aleatórios.

public class MainClass {

    private static long depth=0L;

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

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

}

15
Não é o caso que esta cauda é recursiva e nunca deve transbordar? Edit: Desculpe. Em Java, ele travou em 8027; no Scala, chegava a 8594755 antes de eu ficar entediado.
arya de

9
@arya, uma parte importante da semântica da JVM é que a recursão final não é suportada. Isso oferece muitos problemas interessantes para aqueles que desejam implementar linguagens com recursão de cauda na JVM.
Thorbjørn Ravn Andersen

2
public foo() { try { foo(); } finally { foo(); } }pode ser executado "virtualmente" para sempre, embora apenas em java.
Felype

para mim, StackOverflowErrorocorre depois de 8792
ericdemo07

2
@ ThorbjørnRavnAndersen A otimização da recursão da cauda não é suportada. Obviamente, você pode ter recursão de cauda. Ele simplesmente não o otimiza para não aumentar a pilha de chamadas.
slim

19

O tamanho da pilha pode ser definido com a -Xssopção de linha de comando, mas, como regra geral, é profundo o suficiente, centenas, senão milhares de chamadas. (O padrão depende da plataforma, mas pelo menos 256k na maioria das plataformas.)

Se você obtiver um estouro de pilha, 99% das vezes é causado por um erro no código.


3
1 para o segundo parágrafo. Deve-se sempre lembrar disso.
mcveat

6
Usando o eclipse, recebo apenas 1024 chamadas recursivas.
Norswap

2
@Norswap Você está determinando isso pelo tamanho do rastreamento de pilha? Isso parece estar limitado a 1024, independentemente do tamanho real da pilha.
Brian McCutchon de

4

Compare essas duas chamadas:
(1) Método estático:

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) Método não estático usando uma classe diferente:

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

A classe de recursão de teste tem public int testRecursion(int number) {como único método.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.