2011-01-19 15 views
78

¿Qué tan profundo debo ingresar a la pila de llamadas antes de obtener un StackOverflowError? ¿La plataforma de respuesta es dependiente?¿Cuál es la profundidad máxima de la pila de llamadas java?

+1

Muy relacionado: http://stackoverflow.com/questions/794227/how-to-know-about-outofmemory-or-stackoverflow-errors-ahead-of-time – finnw

+0

Dado que esta es una buena pregunta, he actualicé el título a algo que siento que está más claramente asociado con el significado. (Anteriormente, pensé que te estarías refiriendo a la profundidad de una pila * particular * que habías capturado en tiempo de ejecución, por ejemplo). Siéntete libre de cambiarlo si no estás de acuerdo. –

+0

@Andrzej - sin objeciones. – ripper234

Respuesta

19

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

Si obtiene un desbordamiento de la pila, el 99% del tiempo es causado por un error en el código.

+3

+1 para el segundo párrafo. Uno siempre debe recordar acerca de eso. – mcveat

+6

Usando eclipse, solo recibo 1024 llamadas recursivas. – Norswap

+0

@Norswap ¿Lo está determinando por el tamaño del seguimiento de pila? Eso parece estar limitado a 1024 independientemente del tamaño real de la pila. –

21

Probé en mi sistema y no encontré ningún valor constante, a veces el desbordamiento de pila ocurre después de las llamadas 8900, 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(); 
    } 

} 
+7

¿No es el caso que esto es recursivo en la cola y no debería desbordarse nunca? Editar: Lo siento. En Java, se bloqueó en 8027; en Scala llegó a 8594755 antes de que me aburriera. – arya

+6

@arya una parte importante de la semántica de JVM es que la repetición de cola no es compatible. Esto ofrece muchos problemas interesantes para aquellos que quieren implementar lenguajes con recursión de cola en la JVM. –

+1

'public foo() {try {foo(); } finalmente {foo(); }} ' puede ejecutarse 'virtualmente' para siempre, solo en java. – Felype

2

comparar estos 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 usando una clase diferente: Clase de recursión

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 

prueba tiene public int testRecursion(int number) { como el único método.

Cuestiones relacionadas