¿Cuál es la profundidad máxima de la pila de llamadas de Java?

100

¿Qué tan profundo necesito entrar en la pila de llamadas antes de obtener un StackOverflowError? ¿Depende la plataforma de respuesta?

destripador234
fuente
1
Estrechamente relacionado: stackoverflow.com/questions/794227/…
finnw
Como esta es una buena pregunta, he actualizado el título a algo que creo que está más claramente asociado con el significado. (Anteriormente pensé que podría estar refiriéndose a la profundidad de una pila en particular que había capturado en tiempo de ejecución, por ejemplo). No dude en volver a cambiarlo si no está de acuerdo.
Andrzej Doyle

Respuestas:

31

Probé en mi sistema y no encontré ningún valor constante, a veces se produce un desbordamiento de pila después de 8900 llamadas, a veces solo después de 7700, números aleatorios.

public class MainClass {

    private static long depth=0L;

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

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

}
Troya
fuente
15
¿No es cierto que esta cola es recursiva y nunca debería desbordarse? Editar: Lo siento. En Java se estrelló en 8027; en Scala subió a 8594755 antes de que me aburriera.
arya
9
@arya una parte importante de la semántica de JVM es que no se admite la recursividad de cola. Esto genera muchos problemas interesantes para aquellos que desean implementar lenguajes con recursividad de cola en la JVM.
Thorbjørn Ravn Andersen
2
public foo() { try { foo(); } finally { foo(); } }puede ejecutarse 'virtualmente' para siempre, aunque solo en Java.
Felype
para mí, StackOverflowErrorocurre después de 8792
ericdemo07
2
La optimización de recursividad de cola de @ ThorbjørnRavnAndersen no es compatible. Obviamente, puede tener recursividad de cola. Simplemente no lo optimiza para no hacer crecer la pila de llamadas.
delgado
19

El tamaño de la pila se puede configurar con el -Xssinterruptor de la línea de comando, pero como regla general, es lo suficientemente profundo, cientos, si no miles, de llamadas. (El valor predeterminado depende de la plataforma, pero al menos 256k en la mayoría de las plataformas).

Si obtiene un desbordamiento de pila, el 99% de las veces es causado por un error en el código.

biziclop
fuente
3
+1 para el segundo párrafo. Uno siempre debe recordar eso.
mcveat
6
Usando eclipse, solo recibo 1024 llamadas recursivas.
Norswap
2
@Norswap ¿Está determinando eso por el tamaño del seguimiento de la pila? Eso parece estar limitado a 1024 independientemente del tamaño real de la pila.
Brian McCutchon
4

Compare estas dos llamadas:
(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 no estático con una clase 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

La clase de recursividad de prueba tiene public int testRecursion(int number) {como único método.

sesenta árboles
fuente