Какова максимальная глубина стека вызовов Java?
Насколько глубоко мне нужно войти в стек вызовов, прежде чем я получу StackruError? Зависит ли платформа от ответов?
5 ответов
Это зависит от количества виртуальной памяти, выделенной для стека.
http://www.odi.ch/weblog/posting.php?posting=411
Вы можете настроить это с -Xss
Параметр VM или с Thread(ThreadGroup, Runnable, String, long)
конструктор.
Я протестировал в своей системе и не нашел никакого постоянного значения, иногда переполнение стека происходит после 8900 вызовов, иногда только после 7700, случайных чисел.
public class MainClass {
private static long depth=0L;
public static void main(String[] args){
deep();
}
private static void deep(){
System.err.println(++depth);
deep();
}
}
Размер стека может быть установлен с помощью -Xss
переключатель командной строки, но, как правило, он достаточно глубокий, сотни, если не тысячи вызовов. (Значение по умолчанию зависит от платформы, но не менее 256 КБ на большинстве платформ.)
Если вы получаете переполнение стека, в 99% случаев это происходит из-за ошибки в коде.
Сравните эти два звонка:
(1) Статический метод:
public static void main(String[] args) {
int i = 14400;
while(true){
int myResult = testRecursion(i);
System.out.println(myResult);
i++;
}
}
public static int testRecursion(int number) {
if (number == 1) {
return 1;
} else {
int result = 1 + testRecursion(number - 1);
return result;
}
}
//Exception in thread "main" java.lang.StackruError after 62844
(2) Нестатический метод с использованием другого класса:
public static void main(String[] args) {
int i = 14400;
while(true){
TestRecursion tr = new TestRecursion ();
int myResult = tr.testRecursion(i);
System.out.println(myResult);
i++;
}
}
//Exception in thread "main" java.lang.StackruError after 14002
Тестовый рекурсивный класс имеет public int testRecursion(int number) {
как единственный метод.
Обходя дерево с огромной глубиной, мы могли столкнуться с этим
/**
* -Xss10M
* max call stack count 92766
* -Xss100M
* max call stack count 2148286
*/
public class MaxCallStack {
private Integer stackCount = 0;
public static void main(String[] args) {
MaxCallStack maxStack = new MaxCallStack();
maxStack.evaluate();
}
private void evaluate() {
try {
Tree tree = new Tree();
tree.left = tree;
traverse(tree);
} catch (StackOverflowError e) {
System.out.println(String.format("max call stack count %s", stackCount));
}
}
private void traverse(Tree tree) {
stackCount++;
if (tree.left != null) {
traverse(tree.left);
}
if (tree.right != null) {
traverse(tree.right);
}
}
private class Tree {
Tree left;
Tree right;
}
}