Саморекурсивный метод в Java вызовет StackOverflowError
, если
nos_levels * frame_size + overhead > stack_size
, где
nos_levels
- глубина рекурсии, необходимая для задачи frame_size
- это размер (в байтах) кадра стека для рекурсивного метода, overhead
представляет использование стека (в байтах) методов, которые запускают рекурсивное вычисление (например, вашmain
method, etcetera) stack_size
- размер стека (в байтах).
Теперь вы реализовали рекурсивные версии факториала и фибонации.Обе версии вернутся на глубину 3000 для расчета fibonacci(3000)
или factorial(3000)
.И оба будут использовать стек одинакового размера и иметь одинаковые накладные расходы.
Разница, объясняющая, почему один сбой, а другой нет, заключается в размере кадра стека.
Теперь кадр стека обычно содержит следующее:
- указатель кадра, который указывает на кадр стека для родительского метода
- адрес возврата
- параметры метода
- объявленные локальные переменные метода
- любые неназванные временные переменные, необходимые для хранения промежуточных значений.
Фактическое число будет зависеть от кодаметод и то, как компилятор JIT отображает переменные в слоты в кадре стека.
Очевидно, что ваши функции достаточно различны, поэтому им нужны стеки разного размера.Я не проверял это, но подозреваю, что это println
заявления, которые делают это.Или, более конкретно, дополнительные скрытые переменные, необходимые для хранения промежуточных переменных, используемых при конкатенации строковых аргументов.
Если вы хотите быть уверенными, вам нужно взглянуть на код, генерируемый JIT-компилятором.