2011-11-19 3 views
4

난 그냥이 기사를 읽어 물체가 invisible 상태에 들어갔을 때 섹션 "A.3.3 보이지 않는"에서 The Truth About Garbage Collection'보이지 않는'물체가 즉시 수집되지 않는 이유는 무엇입니까?

는 어떻게 설명한다. 아래의 코드에서

변수 foo에 할당 된 객체는 try/catch 블록을 떠난 후 invisible 될 것이며합니다 ( while 루프가 영원히 실행되기 때문에, 결코 일어나지 않을 것이다) remainly 강하게 run 방법이 종료 될 때까지 참조 할 것이다.

public void run() { 
    try { 
     Object foo = new Object(); 
     foo.doSomething(); 
    } catch (Exception e) { 
     // whatever 
    } 
    while (true) { // do stuff } // loop forever 
} 

이 문서에 명시되어이 범위를 벗어나면

그러나, JVM의 효율적인 구현이 제로 기준으로 않을 수 있습니다.

왜 그렇게 효율적이지 않습니까?

이 방법의 스택이 지금 보이지 않는 개체가 하단에있는 네 개의 요소를 포함 말 다음과 같이 설명에서

내 시도이다.
개체를 즉시 수집하려면 세 개의 요소를 팝하고 저장 한 다음 네 번째 요소를 팝하고 무시한 다음 세 개의 유효한 요소를 다시 스택으로 푸시해야합니다.
제어 흐름이 run 메서드를 벗어난 후에 보이지 않는 개체를 수집하면 VM은 네 개의 요소를 모두 팝하고 무시할 수 있습니다.

+0

관련없는 코드를 같은 방법으로 혼합하지 않는 것이 좋습니다. 혼동하는 코드는 JVM을 혼란스럽게합니다. –

답변

3

지역 변수는 피연산자 스택에 없지만 aloadastore 바이트 코드를 통한 참조의 경우 액세스 한 로컬 변수 영역에서 로컬 변수를 0으로 설정하는 것은 푸시 및 팝핑을 포함하지 않습니다. 가 필요하지 않기 때문에

영점은 비효율적이다 : 프로그램의 논리에 의해 결정대로 즉시 가비지 콜렉션주기

  • 제로 곧 다른 값으로 덮어 쓸 수 있습니다 발생하지 것이다

    • .
    • 범위를 벗어나는 것은 로컬 변수가 더 이상 가비지 수집을위한 루트 집합의 일부가 아니라는 것을 의미합니다. 범위에서 벗어나기 직전에 보류 된 가치 (0 또는 유효한 참조)는 중요하지 않습니다. 그것은 어쨌든 조사되지 않을 것입니다.

    편집 : 마지막 문에

    일부 의견.

    실제로 바이트 코드 수준에서는 범위가없고 로컬 변수 슬롯은 메서드가 반환 될 때까지 루트 집합의 일부로 남아있을 수 있습니다. 물론, JVM 구현은 로컬 변수 슬롯이 죽었을 때를 결정할 수 있습니다 (즉, 메소드 반환에 대한 모든 가능한 경로는 변수에 액세스하지 않거나 상점 임). 루트 집합의 일부로 간주하지 않습니다. 결코 그렇게 할 필요는 없습니다.

  • +0

    * 범위를 벗어나면 로컬 변수가 더 이상 가비지 수집을위한 루트 집합에 속하지 않음을 의미합니다. *이 값이 올바르지 않습니다. 객체가 실제로 더 이상 사용되지 않을 때 가비지 자료를 고려합니다. 즉, 더 이상 참조가 없을 때 에. 예를 들어'{Object a = new Object(); a.hashCode(); // 더 이상 쓰레기 물질에 대한 참조가 없다면}'. – bestsss

    +0

    @bestsss, 아마도 당신은 다른 말을하고 싶었을 것입니다. 왜냐하면이 양식에서 당신의 코멘트는별로 의미가 없기 때문입니까? – chill

    +0

    JVM은 Java에서 범위를 정의하므로 범위를 인식하지 못합니다. 대괄호 {}는 바이트 코드에서도 범위를 정의하지는 않습니다. 실제로 '프레임'이 있지만 범위를 지정하지는 않습니다. 이전 코멘트에서 'a.hashCode()'후에 무한 루프가 존재하더라도 더 이상 참조되지 않는다면 GC는 'a'를 자유롭게 수집 할 수 있습니다. 편집에 관해서는 JVM이 전혀 수집 할 필요가 없으며 모든 가비지 수집기가없는 JVM이있을 수 있습니다. – bestsss

    0

    매우 간단한 대답은 b/c가 비효율적이라는 것입니다.

    가비지 수집기 알고리즘이 많으며 일부는 적극적으로 수집 할 수 있습니다. 일부 컴파일러는 스택에 할당을하지만 가장 확실한 경우는 doSomething()이 실제로 다른 곳의 객체에 대한 참조를 유지할 수 있습니다.