Qual è la profondità massima dello stack di chiamate java?


100

Quanto in profondità devo entrare nello stack di chiamate prima di ottenere StackOverflowError? La piattaforma di risposta dipende?


1
Strettamente correlato: stackoverflow.com/questions/794227/...
finnw

Poiché questa è una buona domanda, ho aggiornato il titolo a qualcosa che ritengo sia più chiaramente associato al significato. (In precedenza pensavo che ti stessi riferendo alla profondità di un particolare stack che avresti catturato in fase di esecuzione, ad esempio). Sentiti libero di cambiarlo di nuovo se non sei d'accordo.
Andrzej Doyle

Risposte:



31

Ho eseguito il test sul mio sistema e non ho trovato alcun valore costante, a volte lo stack overflow si verifica dopo 8900 chiamate, a volte solo dopo 7700, numeri casuali.

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
Non è il caso che questa sia ricorsiva alla coda e non dovrebbe mai traboccare? Modifica: scusa. In Java si è bloccato a 8027; in Scala è arrivato a 8594755 prima che mi annoiassi.
arya

9
@arya una parte importante della semantica JVM è che la ricorsione in coda non è supportata. Questo crea molti problemi interessanti per coloro che vogliono implementare linguaggi con ricorsione in coda sulla JVM.
Thorbjørn Ravn Andersen

2
public foo() { try { foo(); } finally { foo(); } }può funzionare "virtualmente" per sempre, ma solo in Java.
Felype

per me, si StackOverflowErrorverifica dopo l'8792
ericdemo07

2
@ ThorbjørnRavnAndersen l' ottimizzazione della ricorsione della coda non è supportata. Piuttosto ovviamente puoi avere la ricorsione della coda. Semplicemente non lo ottimizza per non aumentare lo stack di chiamate.
slim

19

La dimensione dello stack può essere impostata con -Xss interruttore della riga di comando ma, come regola generale, è abbastanza profonda, centinaia se non migliaia di chiamate. (L'impostazione predefinita dipende dalla piattaforma, ma almeno 256k nella maggior parte delle piattaforme.)

Se si verifica un overflow dello stack, il 99% delle volte è causato da un errore nel codice.


3
+1 per il secondo paragrafo. Uno dovrebbe sempre ricordarlo.
mcveat

6
Usando eclipse, ottengo solo 1024 chiamate ricorsive.
Norswap

2
@Norswap Lo stai determinando dalla dimensione dell'analisi dello stack? Sembra essere limitato a 1024 indipendentemente dalle dimensioni effettive dello stack.
Brian McCutchon

4

Confronta queste due chiamate:
(1) Metodo statico:

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) Metodo non statico che utilizza una classe diversa:

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 classe di ricorsione test ha public int testRecursion(int number) {come unico metodo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.