2010-04-21 6 views
2

.NET 관리 세계의 정적 객체가 결코 가비지 수집되지 않을 로더 힙에로드된다는 것을 알고 있습니다.정적 메서드에 전달 된 인스턴스 참조 매개 변수가 가비지 수집됩니까?

정적 메서드에 전달 된 인스턴스 참조 매개 변수는 어떻게됩니까? 정적 함수가 완전히 실행되면 가비지 수집됩니까? 아니면 인스턴스 참조 변수가 정적 메서드로 전달되면 영원히 살려고합니까?

나는 오늘 저녁에 정말로 혼란 스럽다. 나를 안내 해줘.

감사합니다.

123Developer입니다.

답변

3

예, 정적 함수가 실행 된 후 가비지 수집됩니다. 비 정적 컨텍스트에서 객체를 작성하므로 로더 힙에 객체가 작성되지 않습니다. 정적 함수에 대한 참조를 전달하면 아무것도 변경되지 않습니다.

1

정적 메서드가 변수로 완료되면 더 이상 참조를 보유하지 않습니다 (정적 변수에 할당하면 다른 개념입니다). 그렇다고해서 즉시 가비지 수집된다는 의미는 아닙니다. 특별히 GC가 실행되도록 지시하지 않는 한, 런타임이 메모리를 확보해야 할 때를 기준으로합니다. 사실, 이것은 응용 프로그램의 수명 동안 (자원이 응용 프로그램 종료와 함께 해제 될 것입니다)되지 않을 수도 있습니다. 기술적으로 가능하지만 이것은 거의 불가능합니다.

+0

수정 - 인스턴스 변수를 정적 필드에 할당하거나 참조를 하나의 필드에 저장하지 않는 한 수정하십시오. – saret

2

정적 메서드에 대한 참조를 전달한다는 것은 개체가 어떤 식 으로든 루팅된다는 것을 의미하지 않으므로 개체가 수집되지 못하도록하는 것만으로는 충분하지 않습니다.

메서드 호출 중에 수집 할 수 있는지 여부는 인수를 사용하여 수행하는 작업과 메서드 호출 외부에서 개체가 사용 중인지 여부에 따라 달라집니다.

예를 들어,이 가상의 코드를 고려해이 경우

public static class Program() 
{ 
    public static void Main() 
    { 
     SomeObject o = new SomeObject(); 
     OtherMethod(o); 
    } 

    private static void OtherMethod(SomeObject x) 
    { 
     // lots of code here, but none that uses x 
    } 
} 

를, O는 OtherMethod에 통화 중에 수집 할 수 컴파일하고 릴리스 빌드를 실행 제공. 릴리스 빌드의 경우, 더 이상 사용되지 않는 변수 및 매개 변수는 사용하지 않는 것으로 간주되어 죽은 것으로 간주되므로 더 이상 객체에 대한 라이브 참조가 있는지 확인할 때 계산되지 않습니다.

디버그 빌드에서는 메서드를 반환 할 때까지 모든 변수와 매개 변수가 인위적으로 유지되므로 브레이크 포인트를 설정하고 변수를 검사 할 수 있습니다. 코드를 사용하는 코드가 남아 있지는 않더라도 변수를 검사 할 수 있습니다.

디버그 빌드에서 위의 코드를 실행하면 Main이 반환 될 때까지 객체가 활성 상태로 유지됩니다.

+0

+1 매우 흥미로운 추가 정보. 그걸 몰랐다. 레슨 : 다시 배웠습니다 : 디버그 및 릴리스 빌드는 외부에서 동일하게 보이지만 후드에서는 매우 다르게 작동합니다. –

+0

일일 투표 한도 때문에 약속 된 upvote를 줄 수 없습니다. ( –

+0

+1 사람들은 이것을 깨닫지 않아야합니다. 그리고 엄청나게 당당한 태도를 취하기 위해서는 CLR이 인스턴스를 GC 전에도 사용할 수 없도록하는 것을 사양에서 제외합니다 변수 'o'는 해당 멤버가 절대 참조 해제되지 않기 때문에 할당됩니다. 실제로 CLR에는 아직 정교한 경험적 방법이 없지만 이론적으로는 가능합니다. –

관련 문제