Какая ошибка возникает в Java при падении приложения из-за бесконечной рекурсии?

«Какая ошибка возникает в Java при падении приложения из-за бесконечной рекурсии?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

При переполнении стека вызовов (call stack) из-за бесконечной или слишком глубокой рекурсии JVM выбрасывает java.lang.StackOverflowError. Это unchecked-исключение (наследник VirtualMachineError), которое указывает на исчерпание ресурсов стека потока.

Причины возникновения:

  • Бесконечная рекурсия (отсутствие базового случая).
  • Чрезмерно глубокая, но корректная рекурсия.
  • Взаимная рекурсия (метод A вызывает метод B, который вызывает метод A).

Пример:

public class RecursionDemo {
    // Бесконечная рекурсия – отсутствует условие выхода
    public static void infiniteRecursion() {
        infiniteRecursion(); // Каждый вызов добавляет фрейм в стек
    }

    public static void main(String[] args) {
        infiniteRecursion(); // Вызовет StackOverflowError
    }
}

Вывод в консоли:

Exception in thread "main" java.lang.StackOverflowError
    at RecursionDemo.infiniteRecursion(RecursionDemo.java:4)
    at RecursionDemo.infiniteRecursion(RecursionDemo.java:4)
    ... (тысячи повторяющихся строк)

Как избежать:

  1. Убедитесь в наличии корректного базового случая в рекурсивной функции.
  2. Преобразуйте рекурсию в итерацию (цикл) для алгоритмов с большой глубиной.
  3. Увеличьте размер стека через JVM-опцию -Xss (например, -Xss2m для 2 МБ), но это лишь временное решение.
  4. Используйте хвостовую рекурсию (tail recursion), но note: стандартная JVM не выполняет её автоматическую оптимизацию (TCO), в отличие от некоторых других языков.

Отличие от других ошибок:

  • StackOverflowError – переполнение стека (области памяти для вызовов методов и локальных переменных).
  • OutOfMemoryError – переполнение кучи (heap, область для объектов).