Zitiert von MSDN über StackOverflowException :
Die Ausnahme, die ausgelöst wird, wenn der Ausführungsstapel überläuft, weil er zu viele verschachtelte Methodenaufrufe enthält.
Too many
ist hier ziemlich vage. Woher weiß ich, wenn zu viele wirklich zu viele sind? Tausende Funktionsaufrufe? Millionen? Ich gehe davon aus, dass es in irgendeiner Weise mit der Größe des Arbeitsspeichers im Computer zusammenhängt, aber ist es möglich, eine ungefähr genaue Größenordnung zu finden?
Ich mache mir darüber Sorgen, weil ich ein Projekt entwickle, bei dem rekursive Strukturen und rekursive Funktionsaufrufe häufig verwendet werden. Ich möchte nicht, dass die Anwendung versagt, wenn ich sie für mehr als nur kleine Tests benutze.
.net
exceptions
recursion
stackoverflow
Marco-Fiset
quelle
quelle
Stack<T>
.editbin /stack:WHATEVER-NUMBER-YOU-LIKE yourexefile.exe
.Antworten:
Es sei denn , Ihre Sprachumgebung unterstützt Endrekursion Optimierung (und Ihre Rekursion ist ein Endaufruf), eine Faustregel ist: Rekursionstiefe sollte O (log n), dh unter Verwendung von Algorithmen oder Datenstrukturen gewährleistet werden , auf der Grundlage sein divide-and Erobern (wie Bäume, die meisten Sortieralogorithmen usw.) ist in Ordnung, aber alles, was linear ist (wie rekursive Implementierungen der Behandlung verknüpfter Listen), ist es nicht.
quelle
Standardmäßig weist die CLR dem Stapel für jeden Thread 1 MB zu (siehe diesen Artikel ). Es sind jedoch viele Anrufe erforderlich, um diesen Betrag zu überschreiten. Dies hängt davon ab, wie viel Speicherplatz auf dem Stack von jedem Aufruf für Parameter und lokale Variablen verwendet wird.
Sie können es sogar
StackOverflowException
mit einem einzigen Anruf zum Werfen bringen , wenn Sie bereit sind, etwas unorthodox zu sein:quelle
Da Cole Campbell die Speichergröße und Michael Borgwardt die Tail-Call-Optimierung bemerkte, werde ich diese nicht behandeln.
Zu beachten ist auch CPS, mit dem mehrere verwobene Funktionen optimiert werden können, während die Tail-Call-Optimierung für einzelne Funktionen vorgesehen ist.
Sie können den Stapel wie hier vergrößern und sich darüber im Klaren sein, dass 64-Bit-Code den Stapel schneller als 32-Bit-Code auffrisst.
Bemerkenswert ist, dass wir eines der Beispiele unter F # Interactive mehr als 40 Stunden lang ausgeführt haben, ohne den Stapel zu sprengen. Ja, es war ein Funktionsaufruf, der von selbst kontinuierlich bis zum erfolgreichen Abschluss lief.
Wenn Sie eine Codeabdeckung durchführen müssen, um herauszufinden, wo die Probleme auftreten, und keine Codeabdeckung mit VS haben, die Sie verwenden können, verwenden Sie TestDriven.NET
quelle