Цитируется из MSDN о StackOverflowException :
Исключение, которое выдается при переполнении стека выполнения, поскольку он содержит слишком много вложенных вызовов методов.
Too many
здесь довольно расплывчато Как я знаю, когда слишком много на самом деле слишком много? Тысячи вызовов функций? Миллионы? Я предполагаю, что это должно быть каким-то образом связано с количеством памяти в компьютере, но возможно ли придумать примерно точный порядок величины?
Я обеспокоен этим, потому что я разрабатываю проект, который включает интенсивное использование рекурсивных структур и рекурсивных вызовов функций. Я не хочу, чтобы приложение не работало, когда я начинаю использовать его не только для небольших тестов.
.net
exceptions
recursion
stackoverflow
марко-fiset
источник
источник
Stack<T>
.editbin /stack:WHATEVER-NUMBER-YOU-LIKE yourexefile.exe
.Ответы:
Если ваша языковая среда не поддерживает оптимизацию хвостовых вызовов (а ваша рекурсия - это хвостовой вызов), основное практическое правило: глубина рекурсии должна быть гарантированно равна O (log n), т. Е. С использованием алгоритмов или структур данных, основанных на разделяющем и conquer (например, деревья, большинство алгоритмов сортировки и т. д.) - это нормально, но все линейное (например, рекурсивные реализации обработки связанных списков) - нет.
источник
По умолчанию CLR выделяет 1 МБ стека для каждого потока (см. Эту статью ). Таким образом, однако, сколько звонков требуется, чтобы превысить эту сумму. Это будет зависеть от того, сколько места в стеке использует каждый вызов для таких вещей, как параметры и локальные переменные.
Вы даже можете сделать это
StackOverflowException
с помощью одного звонка, если хотите быть немного неортодоксальным:источник
Поскольку Коул Кэмпбелл отметил объем памяти, а Майкл Боргвардт отметил оптимизацию хвостового вызова, я не буду их освещать.
Еще одна вещь, о которой следует знать, это CPS, который можно использовать для оптимизации нескольких переплетенных функций, где оптимизация хвостового вызова предназначена для отдельных функций.
Вы можете увеличить размер стека, как мы делали здесь , и помните, что 64-битный код потребляет стек быстрее, чем 32-битный код.
Следует отметить, что мы запустили один из примеров в интерактивном режиме F # более 40 часов без потери стека. Да, это был один вызов функции, который выполнялся сам по себе непрерывно до успешного завершения.
Кроме того, если вам нужно выполнить покрытие кода, чтобы выяснить, где возникают проблемы, и нет покрытия кода с VS, которое вы можете использовать, TestDriven.NET
источник