Java 호출 스택의 최대 깊이는 얼마입니까?


100

StackOverflowError가 발생하기 전에 호출 스택에 얼마나 깊이 들어가야합니까? 답변 플랫폼이 종속적입니까?


1
밀접한 관련이 있음 : stackoverflow.com/questions/794227/…
finnw

이것은 좋은 질문이기 때문에 의미와 더 명확하게 연관되어 있다고 생각되는 제목으로 업데이트했습니다. (이전에는 예를 들어 런타임에 캡처 한 특정 스택 의 깊이를 참조 할 수 있다고 생각했습니다 .) 동의하지 않으면 다시 변경하십시오.
Andrzej Doyle

답변:


60

스택에 할당 된 가상 메모리의 양에 따라 다릅니다.

http://www.odi.ch/weblog/posting.php?posting=411

-XssVM 매개 변수 또는 Thread(ThreadGroup, Runnable, String, long)생성자를 사용하여 이를 조정할 수 있습니다 .


13
그리고 아마도 스택 프레임의 크기는 무엇입니까?
duffymo 2011 년

1
제한은 함수의 스택 사용량에 따라 다릅니다.
Jarek Przygódzki

1
우리가 Xss를 언급하지 않으면?
a3.14_Infinity

31

내 시스템에서 테스트했지만 상수 값을 찾지 못했습니다. 때로는 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();
    }

}

15
이것이 꼬리 재귀이고 절대로 오버플로되지 않아야하는 경우 아닌가요? 편집 : 죄송합니다. Java에서는 8027에서 충돌했습니다. Scala에서는 지루해지기 전에 8594755까지 올라갔습니다.
아리아

9
@arya JVM 의미 체계의 중요한 부분은 꼬리 재귀가 지원되지 않는다는 것입니다. 이것은 JVM에서 꼬리 재귀를 사용하여 언어를 구현하려는 사람들에게 많은 흥미로운 문제를 제공합니다.
Thorbjørn Ravn Andersen

2
public foo() { try { foo(); } finally { foo(); } }하지만 Java에서만 '가상'으로 영원히 실행할 수 있습니다.
Felype 2015 년

나를 위해, StackOverflowError발생 후 8792 후
ericdemo07

2
@ ThorbjørnRavnAndersen 꼬리 재귀 최적화 는 지원되지 않습니다. 오히려 분명히 꼬리 재귀를 가질 수 있습니다. 호출 스택을 늘리지 않도록 최적화하지 않습니다.
slim

19

스택 크기는 -Xss명령 줄 스위치 로 설정할 수 있지만 경험 상으로는 충분히 깊습니다. 수천 건은 아니더라도 수백 건의 호출 깊이입니다. (기본값은 플랫폼에 따라 다르지만 대부분의 플랫폼에서 최소 256k입니다.)

스택 오버플로가 발생하면 99 %의 시간이 코드 오류로 인한 것입니다.


3
두 번째 단락의 경우 +1. 항상 그것에 대해 기억해야합니다.
mcveat 2011 년

6
이클립스를 사용하면 1024 개의 재귀 호출 만받습니다.
Norswap 2013 년

2
@Norswap 스택 추적의 크기로 결정하고 있습니까? 스택의 실제 크기에 관계없이 1024로 제한되는 것으로 보입니다.
Brian McCutchon

4

다음 두 호출을 비교합니다.
(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.StackOverflowError 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.StackOverflowError after 14002

테스트 재귀 클래스는 public int testRecursion(int number) {유일한 방법입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.