2011-01-19 16 views
78

In che misura ho bisogno di entrare nello stack di chiamate prima di ottenere un StackOverflowError? La piattaforma di risposta è dipendente?Qual è la profondità massima dello stack di chiamate java?

+1

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

+0

Poiché questa è una buona domanda, ho aggiornato il titolo a qualcosa che ritengo sia associato più chiaramente al significato. (In precedenza ho pensato che potreste riferirvi alla profondità di uno * particolare * stack che avete catturato in fase di runtime, per esempio). Sentiti libero di cambiarlo se non sei d'accordo. –

+0

@Andrzej - nessuna obiezione. – ripper234

risposta

19

La dimensione dello stack può essere impostata con l'interruttore della riga di comando -Xss ma, in linea di massima, è abbastanza profondo, centinaia se non migliaia di chiamate in profondità. (L'impostazione predefinita dipende dalla piattaforma, ma almeno 256k nella maggior parte delle piattaforme.)

Se si verifica un overflow di 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, ricevo solo 1024 chiamate ricorsive. – Norswap

+0

@Norswap Lo stai determinando in base alla dimensione della traccia dello stack? Sembra essere limitato a 1024 indipendentemente dalle dimensioni effettive dello stack. –

21

Ho eseguito il test sul sistema e non ho trovato alcun valore costante, a volte l'overflow dello stack 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(); 
    } 

} 
+7

Non è il caso che questo è ricorsivo di coda e non dovrebbe mai traboccare? Modifica: mi dispiace In Java si è schiantato all'8027; in Scala è arrivato a 8594755 prima di annoiarmi. – arya

+6

@arya una parte importante della semantica JVM è che la ricorsione della coda non è supportata. Ciò offre molti problemi interessanti per coloro che desiderano implementare le lingue con ricorsione in coda sulla JVM. –

+1

'public foo() {try {pippo(); } finally {foo(); }} ' può essere eseguito 'virtualmente' per sempre, solo in Java. – Felype

2

confrontare questi 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) il metodo non-statico utilizzando 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 

class Test ricorsione ha public int testRecursion(int number) { come unico metodo.

Problemi correlati