Da dies eine gute Frage ist, habe ich den Titel auf etwas aktualisiert, das meiner Meinung nach klarer mit der Bedeutung zusammenhängt. (Früher dachte ich, Sie beziehen sich möglicherweise auf die Tiefe eines bestimmten Stapels, den Sie beispielsweise zur Laufzeit erfasst haben.) Fühlen Sie sich frei, es zurück zu ändern, wenn Sie nicht einverstanden sind.
Andrzej Doyle
Antworten:
60
Dies hängt von der Menge des dem Stapel zugewiesenen virtuellen Speichers ab.
Und vielleicht die Größe der Stapelrahmen, die Sie darauf setzen?
Duffymo
1
Das Limit hängt auch von der Stapelverwendung in der Funktion ab.
Jarek Przygódzki
1
Wenn wir das Xss nicht erwähnen, dann?
a3.14_Infinity
31
Ich habe auf meinem System getestet und keinen konstanten Wert gefunden. Manchmal tritt ein Stapelüberlauf nach 8900 Aufrufen auf, manchmal erst nach 7700 Zufallszahlen.
Ist es nicht so, dass dies rekursiv ist und niemals überlaufen sollte? Edit: Sorry. In Java stürzte es bei 8027 ab; In Scala waren es 8594755, bevor mir langweilig wurde.
Arya
9
@arya Ein wichtiger Teil der JVM-Semantik ist, dass die Schwanzrekursion nicht unterstützt wird. Dies gibt viele interessante Probleme für diejenigen, die Sprachen mit Schwanzrekursion in der JVM implementieren möchten.
Thorbjørn Ravn Andersen
2
public foo() { try { foo(); } finally { foo(); } }kann "praktisch" für immer laufen, allerdings nur in Java.
Felype
für mich StackOverflowErrortritt nach nach 8792
ericdemo07
2
@ ThorbjørnRavnAndersen Die Optimierung der Schwanzrekursion wird nicht unterstützt. Eher offensichtlich kann man eine Schwanzrekursion haben. Es wird einfach nicht optimiert, um den Aufrufstapel nicht zu vergrößern.
schlank
19
Die Stapelgröße kann mit dem -XssBefehlszeilenschalter festgelegt werden. Als Faustregel gilt jedoch, dass sie tief genug ist, Hunderte, wenn nicht Tausende von Aufrufen. (Die Standardeinstellung ist plattformabhängig, auf den meisten Plattformen jedoch mindestens 256 KB.)
Wenn Sie einen Stapelüberlauf erhalten, wird dieser in 99% der Fälle durch einen Fehler im Code verursacht.
+1 für zweiten Absatz. Daran sollte man sich immer erinnern.
Mcveat
6
Mit Eclipse erhalte ich nur 1024 rekursive Aufrufe.
Norswap
2
@Norswap Bestimmen Sie das anhand der Größe des Stack-Trace? Dies scheint unabhängig von der tatsächlichen Größe des Stapels auf 1024 begrenzt zu sein.
Brian McCutchon
4
Vergleichen Sie diese beiden Aufrufe:
(1) Statische Methode:
publicstaticvoid main(String[] args){int i =14400;while(true){int myResult = testRecursion(i);System.out.println(myResult);
i++;}}publicstaticint testRecursion(int number){if(number ==1){return1;}else{int result =1+ testRecursion(number -1);return result;}}//Exception in thread "main" java.lang.StackOverflowError after 62844
(2) Nicht statische Methode unter Verwendung einer anderen Klasse:
publicstaticvoid main(String[] args){int i =14400;while(true){TestRecursion tr =newTestRecursion();int myResult = tr.testRecursion(i);System.out.println(myResult);
i++;}}//Exception in thread "main" java.lang.StackOverflowError after 14002
Die Testrekursionsklasse ist public int testRecursion(int number) {die einzige Methode.
Antworten:
Dies hängt von der Menge des dem Stapel zugewiesenen virtuellen Speichers ab.
http://www.odi.ch/weblog/posting.php?posting=411
Sie können dies mit dem
-Xss
VM-Parameter oder mit demThread(ThreadGroup, Runnable, String, long)
Konstruktor optimieren .quelle
Ich habe auf meinem System getestet und keinen konstanten Wert gefunden. Manchmal tritt ein Stapelüberlauf nach 8900 Aufrufen auf, manchmal erst nach 7700 Zufallszahlen.
quelle
public foo() { try { foo(); } finally { foo(); } }
kann "praktisch" für immer laufen, allerdings nur in Java.StackOverflowError
tritt nach nach 8792Die Stapelgröße kann mit dem
-Xss
Befehlszeilenschalter festgelegt werden. Als Faustregel gilt jedoch, dass sie tief genug ist, Hunderte, wenn nicht Tausende von Aufrufen. (Die Standardeinstellung ist plattformabhängig, auf den meisten Plattformen jedoch mindestens 256 KB.)Wenn Sie einen Stapelüberlauf erhalten, wird dieser in 99% der Fälle durch einen Fehler im Code verursacht.
quelle
Vergleichen Sie diese beiden Aufrufe:
(1) Statische Methode:
(2) Nicht statische Methode unter Verwendung einer anderen Klasse:
Die Testrekursionsklasse ist
public int testRecursion(int number) {
die einzige Methode.quelle