2013-04-08 2 views
0

임씨는 어떻게 GC/파이널 라이저가 작동하는지 알아 내려고 노력 했으므로 다음 프로그램을 작성했습니다. 그러나 ReadKey 후에 finalizer는 36,193 번 호출됩니다. 프로그램이 끝나고 AppDomain이 언로드 될 때 한 번만 호출되어야한다고 생각했습니다. 내가 여기서 무엇을 놓치고 있는지, 어떻게 작동합니까?파이널 라이저는 어떻게 작동합니까?

private class GCAnalyzer 
    { 
     private static int count = 0; 
     ~GCAnalyzer() 
     { 
      if (!AppDomain.CurrentDomain.IsFinalizingForUnload()) 
      { 
       count++; 
       GC.ReRegisterForFinalize(this); 
       Console.WriteLine("GC " + count); 
      } 
     } 
    } 

    static void Main(string[] a) 
    { 
     new GCAnalyzer(); 

     Console.ReadKey(); 
    } 
+0

msdn 설명서를 읽었습니까? –

+1

마치 가비지 컬렉터가 그것을 기억하고 싶어하는 것처럼 보입니다. –

+4

왜 당신은'ReRegisterForFinalize'을합니까? – Spook

답변

2

나는 당신이 ~ GCAnalyzer() 객체가 "연결되지 않은"이며, 그 코드 동안, 당신이 GC.ReRegisterForFinalize를 통해 "연결을 해제"할 준비가되지 않았 말할 때 (이 호출이 권리를 읽는다면), 다음 체크에서 여전히 사용되지 않고 그 엔드 코드가 실행됨을 의미합니다 ... 자체 등록 ... 등등.

+0

나는 GC 콜렉션이 일어나고있을 때 파이널 라이저가 호출 될 것이라고 생각하고 있었는데, 그 후에 AppDomain이 언로드되어 객체가 다시 등록되지 않게되었습니다. 그럼 어떻게 될까요? finalizer 스레드는 AppDomain이 언로드되기 전에이 finalizer를 계속 유지합니다. ?? – Laurijssen

0

키는! Environment.HasShutdownStarted 검사를 추가하는 것이 었습니다. 그런 다음 모든 컬렉션에서 최종자를 호출하고 최종 목록에 다시 넣습니다. 그래서이 프로그램에서 finalizer는 3 번 호출됩니다. 모든 GC.Collect에 대해 두 번, 그리고 최종 목록에 다시 등록됩니다. 세 번째로 앱이 종료 된 후 다시 등록되지 않으므로 정상적으로 종료됩니다.

private class GCAnalyzer 
    { 
     private static int count = 0; 
     ~GCAnalyzer() 
     { 
      Console.WriteLine("GC " + count); 
      if (!AppDomain.CurrentDomain.IsFinalizingForUnload() &&!Environment.HasShutdownStarted) 
      { 
       count++; 
       GC.ReRegisterForFinalize(this);      
      } 
     } 
    } 

    static void Main(string[] a) 
    { 
     new GCAnalyzer(); 

     Console.ReadKey(); 

     GC.Collect(); 

     Console.ReadKey(); 

     GC.Collect(); 
    } 
관련 문제