2012-04-18 2 views
2

여기 일부 코드이다 b.doSomething를 실행가비지 수집 여부

public class A { 
    private volatile B b; 

    public void methodC() { 
    b.doSomething(); 
    } 

    public void setB(B newB) { 
    this.b = newB; 
    } 
} 

'1 스레드'()를 실행하여 methodC().

동시에 '스레드 2'는 새 B 개체를 'b'로 설정합니다.

내 질문은 :

는 이전에 그 위에 해봐요() 메소드가 여전히 실행되고 있지만 가비지 수집 'B'에 의해 객체 refereced 수 있을까요?

답변

7

아니요, 멤버 함수를 호출하려면 객체에 대한 참조가 필요합니다. 따라서 b.doSomething()을 호출하는 스레드는 참조를 보유하므로 가비지 수집을 방지합니다.

bGC '일 때 상황에 대한 아래의 답변을 확인하십시오.

+0

'thread 1'의 이전 참조 된 객체에 대한 직접 참조 또는 파생 참조가 없다고 생각합니다. GC 문서에서 '도달 가능'하다고 생각하면 직접적으로 또는 파생 된 참조가있는 스레드가 있어야 함을 의미합니다. –

+0

나는 어떤 참조가있을 수 있습니까? –

+0

멤버 함수를 호출하려면 스레드의 스택에있는 객체에 대한 참조가 있어야합니다. 이 함수를 어떻게 호출 할 수 있습니까? – Nick

1

doSomething() 메소드가 아직 실행 중이지만 이전에 'b'에 의해 참조 된 객체가 가비지 수집 될 수 있습니까?

예, 'b'로 이전에 참조 된 개체는 doSomething() 메서드가 실행되고 있어도 가비지 수집 될 수 있습니다.

메서드가 암시 적으로 this 포인터를 전달했기 때문에 해당 메서드 중 하나가 실행되는 동안 this에 연결할 수 있으며 항상 스택에 쏟아져 있다고 가정 할 수 있습니다. 그러나 많은 최적화가 이것을 변경하고 GC에서 볼 수있는 전역 루트 집합에서 this을 제거 할 수 있습니다.

예컨대, doSomething 메소드의 본문 this 필요하지 않은 코드를 종료하고 방법은 스택 레지스터로부터 다음 this 엎되지 않을 인라인 또는 스택 슬롯 덮어 쓸 수있는 경우. 두 경우 모두 실행이 여전히 doSomething 안에 있더라도 GC는 더 이상 this을 볼 수 없으므로 this은 가비지 수집 될 수 있습니다.

+0

+1 아, 지금 무슨 뜻인지 안다. 나는'this' 포인터가'doSomething' 내에서 사용 되리라 생각했지만 맞았습니다 -이 함수 내에서'this'에 대한 참조가 없다면 GC'd를 멈추게 할 아무 것도 없습니다. – Nick

+0

정확하게. 사용 되더라도'doSomething' 함수 안에서 마지막으로 사용한 후에 다시 사용할 수 있습니다. –