2012-09-28 5 views
5

아래 코드가 주어졌습니다.개인 필드의 가비지 수집

class A { 
    private B b; 
    public A() { 
     b = new B(); 
    } 
} 

class Main { 
    public static void main(String[] args) { 
     A a = new A(); // two objects are created (a and b) 
     // <-- is B object, referenced only by private a.b eligible for garbage collection? 
     keepAlive(a); 
    } 
} 

A 개체를 만든 후에 B 개체를 가비지 수집 할 수 있습니까?

답변

6

이 필드는 여전히 반사 (setAccessible(true) 사용)를 통해 액세스 할 수 있기 때문에 아니오라고 생각합니다. 이론적으로

, 컴파일러는이 필드에 액세스되지 않을 것이라고 증명할 수 있고, (JLS 12.6.1 Implementing Finalization에서) 가비지 컬렉션 B 자격 만들 것 :

도달 가능한 객체는 잠재적으로 액세스 할 수있는 객체이다 라이브 스레드에서 계산 계속. 순전히 도달 가능한 것으로 간주되는 것보다 적게 도달 할 수있는 오브젝트의 수를 줄이는 프로그램의 변환을 최적화 할 수 있습니다. 예를 들어, 컴파일러 나 코드 생성기는 더 이상 null로 사용되지 않는 변수 나 매개 변수를 설정하여 이러한 객체에 대한 저장소를 잠재적으로보다 쉽게 ​​회수 할 수 있습니다.

하지만 연습 컴파일러와 JVM의 스마트

1

@Kuba가 무슨 뜻한다는 것을 생각하지 않는다 : 현장 클래스 A의 예를 ab에서 클래스 B의 인스턴스가 쓰레기 수집 할 수 있습니다 ? 아니요. anull이 아니며 ba으로 표시됩니다.

1

아니요, 주 스레드의 경로가 b에서 a까지이므로.

0

표준 컴파일러는 그렇게 똑똑하지 않습니다.

class A 
{ 
    private Object[] array; 

    public A() 
    { 
     array = new Object[10000000]; 
    } 
} 

public static void main(String[] args) 
{ 
    LinkedList<A> list = new LinkedList<A>(); 
    while (true) 
    { 
     list.add(new A()); 
    } 
} 

이 코드는 매우 적은 수의 루프 이후에 예외 메모리를 초과하므로 원래 질문에 대한 대답은 분명히 아니오입니다.