Ответ
При переполнении стека вызовов (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)
... (тысячи повторяющихся строк)
Как избежать:
- Убедитесь в наличии корректного базового случая в рекурсивной функции.
- Преобразуйте рекурсию в итерацию (цикл) для алгоритмов с большой глубиной.
- Увеличьте размер стека через JVM-опцию
-Xss(например,-Xss2mдля 2 МБ), но это лишь временное решение. - Используйте хвостовую рекурсию (tail recursion), но note: стандартная JVM не выполняет её автоматическую оптимизацию (TCO), в отличие от некоторых других языков.
Отличие от других ошибок:
StackOverflowError– переполнение стека (области памяти для вызовов методов и локальных переменных).OutOfMemoryError– переполнение кучи (heap, область для объектов).