2013-04-17 4 views
2

나는 프로그램 아래 실행하면이 StackOverflowError가 있어야한다 나 오세요

class Person{ 
    Person p; 
    Person(){ 
     System.out.println("Hi"); 
     p = new Person(); 
    } 
} 

public class Main { 


    public static void main(String[] args) { 
     new Person(); 
    } 
} 

이 유래 오류 를 throw하지만 우리는하지 로컬 방법/변수, 객체 생성 작업하는 나는, 그것은 오세요 될 것으로 예상 또는 참조 변수

+0

person 클래스 생성자에서 person 객체를 만드는 것처럼 보이고 무한 루프로 진행되는 것처럼 보입니다. – jpw

답변

4

당신은 재귀와 스택에 (적어도, 반환 주소 - 스택이 로컬 변수 및 매개 변수에 사용되지 않음) 데이터를 두는 Person() 생성자를 호출 종료 조건없이 있습니다

을3210
Person(){ 
    p = new Person(); // <<== Calls the Person() constructor, which again calls the Person() constructor, which again ... 
} 

따라서 스택 오버플로 오류가 발생합니다.

이론적으로 컴파일러는 이것이 꼬리 재귀이며 메서드 호출을 최적화하는 것을 볼 수 있지만 이것은 발생하지 않습니다.

Person 개체 자체는 힙에 만들어 지지만 일반적으로 힙은 스택보다 큽니다 (적어도 기본적으로) 스택은 힙보다 먼저 채워집니다.

java -Xss128M -Xmx4M Person 

처럼, 스택 크기 및 최대 힙 크기를 다르게 설정과 같은 응용 프로그램을 실행 시도하고 당신은 오세요 대신 스택 오버 플로우를 얻을 것이다.

+0

생성자가 힙에 데이터를 둡니다. 힙에있는 객체 생성의 일부로이 경우가 아닙니까? –

+0

오브젝트 자체는'new'에 의해 힙에 작성되지만, 여전히 생성자 호출은 최소한 리턴 주소를 스택에 배치합니다. 보통 힙은 스택보다 크기 때문에 스택이 힙 앞에 채워집니다. –

0

이유는 사람의 기본 생성자에서 발생 재귀-호출()이다.

  1. 자바 스택이를 automaticly 확장 할 수있다 ,이 던질거야 : 자바 가상 머신 사양은 자바 스택에 대한 예외의 두 가지 상황을 지배하고있다 : JVM의 지식의 깊은 수준에서

    이 문제를 설명하기 충분한 메모리를 적용 할 수 없을 때 OOM (OutOfMemory) 오류가 발생합니다.

  2. 자바 스택은 스택 프레임으로 구성되며 각 자바 메소드 은 프레임을 푸시합니다. 스택의 깊이가 허용 된 것보다 큰 경우 StackOverflowError를 발생시킵니다.

아마 당신을 도울 수 :

2

당신의 기대가 부당한 없습니다.

여기에 직장에서 두 힘이 있습니다 사람의

  • 객체 생성() 힙이
  • 깊은 재귀를 통해
  • 호출 스택 확대
  • 이 둘 중 하나가 먼저 실패

는 anyones에있다 추측하고 JVM 설정에 크게 의존합니다. -Xmx를 매우 낮은 값으로 설정하면 가장 먼저 OOMException이 발생합니다.

+0

깊은 재귀를 통한 콜 스택 확장 - 일반적으로 스택에서 재귀가 발생합니다. –

관련 문제