Почему стек может переполниться (StackOverflowException) в .NET?

«Почему стек может переполниться (StackOverflowException) в .NET?» — вопрос из категории Управление памятью, который задают на 25% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Переполнение стека (StackOverflowException) возникает, когда стек вызовов (call stack) превышает выделенный ему объём памяти. В .NET это почти всегда следствие логической ошибки в коде, а не нехватки ресурсов.

Основные причины:

  1. Бесконечная или слишком глубокая рекурсия без корректного базового условия.
  2. Взаимная рекурсия (A -> B -> A -> ...).
  3. Очень большие структуры (struct), передаваемые по значению в методы (каждый вызов размещает их копию в стеке).

Пример проблемного кода:

public void Run()
{
    InfiniteRecursion(); // Вызовет StackOverflowException
}

private void InfiniteRecursion()
{
    // Нет условия выхода -> бесконечная цепочка вызовов
    InfiniteRecursion();
}

Как избежать и исправить:

  • Для рекурсии: Всегда проверяйте наличие и корректность базового условия (base case).
  • Рассмотрите итеративный подход: Глубокую рекурсию часто можно заменить циклом с использованием стека или очереди в куче (heap).
  • Для больших структур: Передавайте их по ссылке с модификатором in или ref (если требуется изменение).
  • Увеличение размера стека (через editbin /STACK или настройки потока) — это крайняя мера для специфичных сценариев и не решает логические ошибки.