2012-10-09 2 views
2

: 그것은 유일한 참조 목록이 와서 어떻게 세대 0 [0] 오브젝트 동안GC의 세대 - 다음 코드를 감안할 때 수집 문제

namespace GcDemo 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var list = new List<object>(); 
      Console.WriteLine("list is in {0} generation.", GC.GetGeneration(list)); 
      GC.Collect(); 
      Console.WriteLine("list is in {0} generation.", GC.GetGeneration(list)); 
      GC.Collect(); 
      list.Add(new object()); 
      Console.WriteLine("list is in {0} generation. object is in {1} generation.", GC.GetGeneration(list), GC.GetGeneration(list[0])); 
      GC.Collect(0); 
      Console.WriteLine("list is in {0} generation. object is in {1} generation.", GC.GetGeneration(list), GC.GetGeneration(list[0])); 

     } 
    } 
} 

목록 객체가 2 세대에하지에 알고 GC에서 그것을 수집하십시오. 콜렉트 (0)?

+0

'object' 인스턴스가 수집 될 것으로 기대 했습니까? –

+0

@BrianRasmussen 예. –

+0

왜 그런가? 그것은 여전히 ​​뿌리가 나서 수집 할 자격이 없습니다. gen0 객체가 gen1 또는 2의 객체에 의해 안정적으로 루팅 될 수없는 경우 세대 전체에 대한 아이디어는 무의미합니다. –

답변

2

This article은 간단한 작동 방식을 기록합니다. "세대 간 쓰기 장벽으로 작업하기"절을 읽으십시오. This은 techinque에 대해 자세히 설명하는 또 다른 좋은 블로그 게시물입니다.

요약은 CLR 방출 코드이므로 Gen2 개체가 작성된시기를 감지 할 수 있습니다. Gen0 컬렉션을 수행 할 때 검사하는 데이터 구조 ("카드 테이블")에 쓰기를 기록합니다. 이렇게하면 Gen2 -> Gen0 참조를 메모리의 모든 객체를 걷는 데 드는 전체 비용없이 찾을 수 있습니다.

+1

제이슨에게 많은 감사를드립니다, 당신은 제가 분명하고 이해하기 쉬운 방법으로 주제를 얻을 수 있도록 도와주었습니다. –

1

맞습니까? 귀하의 질문은 GC가 왜 수집되지 않는 이유입니까 list[0]?

list은 내부적으로 사용자가 만든 개체에 대한 참조를 가지고 있기 때문에 (List<T>에는 내부적으로 항목을 보유 할 배열이 T[]이므로) 대답은 다음과 같습니다. ->list ->list[0] 이렇게 보이는 체인의 모양은 다음과 같습니다. 따라서 개체가 어떤 세대인지에 관계없이 GC는이 개체를 수집 할 수 없으며 수집해서도 안됩니다.

편집 : 당신이 세대 0의 수집을 시작하는 경우, ... list[0] (위 참조) =>는 GC list[0]를 수집하지 않지만, 세대 1

로 이동합니다 +는 참조 세대 0에
+0

하지만 세대 0 만 수집합니다. 목록은 2 세대에 있습니다. GC가 어떻게 목록 [0]을 수집하지 않는지 알고 있습니까? –

+0

@ YairNevet : 편집 – ulrichb

+0

참조 GC는 개체에 대한 목록 [0]의 참조를 볼 수 없으며 개체를 수집하지 않고 Gen 1로 수준을 올리기도한다는 것을 "어떻게 든"알고 있습니다. 질문은 다음과 같습니다. "어떻게 든"? –

1

기본 규칙은 매우 간단합니다. 참조가 남아 있지 않으면 개체가 수집됩니다. 목록에 추가 한 개체를 수집 할 수 없으며 목록에 대한 참조가 있습니다. 목록을 수집 할 수 없으며 코드에 대한 참조가 있습니다. 마지막 진술까지. 컬렉션을 강제 할 때마다 개체를 강제로 다음 세대로 이동시킵니다.

가비지 수집기에서 목록에 개체에 대한 참조가 저장되어 있음을 알 수 있다는 점만 혼란 스러울 수 있습니다. 가장 확실합니다. 꼭 그렇게해야만, 당신은 그 물체가 무작위로 사라지는 것을 원하지 않을 것입니다. CLR이 수행하는 작업의 매우 큰 부분은 가비지 수집기에 가능한 한 빨리이를 발견하는 데 필요한 정보를 제공하는 것입니다.

아마도 더 혼란 스러우면 코드에 목록에 대한 참조가 있음을 알 수 있습니다. 이는 지터의 중요한 부분이며, 코드의 어느 부분이 로컬 변수를 참조 하는지를 나타내는 테이블을 구성합니다. 마지막 문장이 목록을 참조하기 때문에 내용 미리보기에서 해당 내용을 볼 수 없습니다.

관련 문제