Quão profundo eu preciso ir na pilha de chamadas antes de obter um StackOverflowError? A resposta da plataforma depende?
Quão profundo eu preciso ir na pilha de chamadas antes de obter um StackOverflowError? A resposta da plataforma depende?
Respostas:
Depende da quantidade de memória virtual alocada para a pilha.
http://www.odi.ch/weblog/posting.php?posting=411
Você pode ajustar isso com o -Xssparâmetro VM ou com o Thread(ThreadGroup, Runnable, String, long)construtor.
Eu testei em meu sistema e não encontrei nenhum valor constante, às vezes o estouro da pilha ocorre após 8.900 chamadas, às vezes somente após 7700, números aleatórios.
public class MainClass {
private static long depth=0L;
public static void main(String[] args){
deep();
}
private static void deep(){
System.err.println(++depth);
deep();
}
}
public foo() { try { foo(); } finally { foo(); } }pode ser executado "virtualmente" para sempre, embora apenas em java.
StackOverflowErrorocorre depois de 8792
O tamanho da pilha pode ser definido com a -Xssopção de linha de comando, mas, como regra geral, é profundo o suficiente, centenas, senão milhares de chamadas. (O padrão depende da plataforma, mas pelo menos 256k na maioria das plataformas.)
Se você obtiver um estouro de pilha, 99% das vezes é causado por um erro no código.
Compare essas duas chamadas:
(1) Método estático:
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.StackOverflowError after 62844
(2) Método não estático usando uma classe diferente:
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.StackOverflowError after 14002
A classe de recursão de teste tem public int testRecursion(int number) {como único método.