Cytat z MSDN na temat StackOverflowException :
Wyjątek zgłaszany, gdy stos wykonania przepełnia się, ponieważ zawiera zbyt wiele zagnieżdżonych wywołań metod.
Too many
jest tu dość niejasne. Skąd mam wiedzieć, kiedy za dużo to naprawdę za dużo? Tysiące wywołań funkcji? Miliony? Zakładam, że musi to być w jakiś sposób związane z ilością pamięci w komputerze, ale czy można wymyślić mniej więcej dokładny rząd wielkości?
Martwię się tym, ponieważ rozwijam projekt, który wymaga intensywnego wykorzystania struktur rekurencyjnych i wywoływania funkcji rekurencyjnych. Nie chcę, aby aplikacja uległa awarii, gdy zacznę jej używać do więcej niż tylko małych testów.
.net
exceptions
recursion
stackoverflow
marco-fiset
źródło
źródło
Stack<T>
.editbin /stack:WHATEVER-NUMBER-YOU-LIKE yourexefile.exe
.Odpowiedzi:
O ile twoje środowisko językowe nie obsługuje optymalizacji ogona (a twoja rekurencja jest ogonem), podstawową zasadą jest: głębokość rekurencji powinna być równa O (log n), tj. Przy użyciu algorytmów lub struktur danych opartych na podziale i podbijanie (jak drzewa, większość alogorytmów sortujących itp.) jest OK, ale nic liniowego (jak rekurencyjne implementacje obsługi połączonych list) nie jest.
źródło
Domyślnie CLR przydziela 1 MB do stosu dla każdego wątku (zobacz ten artykuł ). Tak więc, tyle połączeń potrzeba, aby przekroczyć tę kwotę. To będzie się różnić w zależności od ilości miejsca na stosie, które każde wywołanie wykorzystuje na takie parametry, jak parametry i zmienne lokalne.
Możesz nawet sprawić, że rzucisz
StackOverflowException
jednym telefonem, jeśli chcesz być trochę niekonwencjonalny:źródło
Ponieważ Cole Campbell zauważył rozmiar pamięci, a Michael Borgwardt zauważył optymalizację połączeń ogonowych, nie będę ich opisywał.
Inną rzeczą, o której należy pamiętać, jest CPS, którego można użyć do optymalizacji kilku przeplecionych funkcji, w których optymalizacja wywołania ogona dotyczy pojedynczych funkcji.
Możesz zwiększyć rozmiar stosu, tak jak my tutaj , i pamiętaj, że 64-bitowy kod zjada stos szybciej niż kod 32-bitowy.
Warto zauważyć, że uruchomiliśmy jeden z przykładów pod interaktywnym F # przez ponad 40 godzin bez wysadzenia stosu. Tak, było to jedno wywołanie funkcji, które samo działało nieprzerwanie do pomyślnego zakończenia.
Ponadto, jeśli musisz zrobić pokrycie kodu, aby dowiedzieć się, gdzie występują problemy i nie masz pokrycia kodu VS, możesz użyć TestDriven.NET
źródło