2008-09-29 8 views
224

.NET에서 어떤 상황에서 GC.SuppressFinalize()을 사용해야합니까?언제 GC.SuppressFinalize()를 사용해야합니까?

이 방법을 사용하면 어떤 이점이 있습니까?

+0

내가 파이 나라와는 IDisposable에 대한 몇 가지 질문을 보았다, 유래도 GC.SupressFinalize와 약한 참조에 대해 뭔가를해야 –

+0

내가 약한 참조가 종료 자에 대한 아무것도 많은 일을 생각하지 않는다 - 어쩌면 당신은 더 할 전망 그들에 대한 직접적인 질문. –

+0

Yerp 약한 참조에 관한 별도의 질문을 게시하는 의미였습니다.이 모든 것은 객체 풀을 만들 때 함께 묶을 수 있습니다. 또한 객체 리바이벌에 관한 질문을해야합니다. ReRegisterForFinalize –

답변

243

SuppressFinalize는 finalizer가있는 클래스에서만 호출해야합니다. this 개체가 완전히 정리 된 가비지 수집기 (GC)에 알립니다.

당신은 파이널을 권장으로 IDisposable 패턴은 다음과 같습니다

public class MyClass : IDisposable 
{ 
    private bool disposed = false; 

    protected virtual void Dispose(bool disposing) 
    { 
     if (!disposed) 
     { 
      if (disposing) 
      { 
       // called via myClass.Dispose(). 
       // OK to use any private object references 
      } 
      // Release unmanaged resources. 
      // Set large fields to null.     
      disposed = true; 
     } 
    } 

    public void Dispose() // Implement IDisposable 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 

    ~MyClass() // the finalizer 
    { 
     Dispose(false); 
    } 
} 

일반적으로는 CLR은 만들 때 (그들이 더 비싼 만들 만들기) 파이널 라이저와 객체에 탭을 유지합니다. SuppressFinalize는 개체가 올바르게 정리되었고 마무리 자 대기열로 이동할 필요가 없음을 GC에 알립니다. C++ 소멸자처럼 보이지만, 하나처럼 행동하지는 않습니다.

SuppressFinalize 최적화는 개체가 finalizer 큐에서 대기하는 데 오랜 시간을 소비 할 수 있기 때문에 간단하지 않습니다. 다른 객체에서 SuppressFinalize를 호출하는 것을 유혹하지 마십시오. 그것은 일어날 대기중인 심각한 결함입니다.

귀하의 개체가 IDisposable을 구현하는 경우 finalizer는 필요하지 않지만 설계자는 finalisizer를 사용하는 경우 IDisposable을 구현하여 클래스를 결정적으로 정리할 수 있도록해야한다고 안내합니다.

대부분의 경우 IDisposable을 사용하여 리소스를 정리할 수 있습니다. 객체가 관리되지 않는 리소스에 보관되어 있고 리소스가 정리되도록 보장해야하는 경우에만 파이널 라이저가 필요합니다.

참고 : 코드 작성자가 IDisposable 객체를 올바르게 배치했는지 테스트하기 위해 코더가 자체 IDisposable 클래스의 디버그 디버거에 최종자를 추가하는 경우가 있습니다.

public void Dispose() // Implement IDisposable 
    { 
     Dispose(true); 
    #if DEBUG 
     GC.SuppressFinalize(this); 
    #endif 
    } 

    #if DEBUG 
    ~MyClass() // the finalizer 
    { 
     Dispose(false); 
    } 
    #endif 
+0

귀하의 코드에 동의하지만 디버그 버전에 어설 션을 넣을 것입니다 ... 그리고 폐기되는 리소스가 비싸면 릴리스 버전에 finalizer를 남겨 둡니다. –

+1

첫 번째 코드 스 니펫에서는 IDisposable + finalizer 패턴이 권장되는 패턴을 게시하고 있습니다. 디버깅 코드는 좋지만 산만해질 수 있습니다. 나는 관리되지 않는 리소스를 가진 클래스를 제외하고는 파이널 라이저를 피하는 것을 권장한다. 안전한 파이널 라이저 코드를 작성하는 것은 간단합니다. –

+0

기본 클래스에서 처분 패턴을 사용하고 다른 클래스 중 하나를 확장 할 수 있습니까? –

1

이 메서드는 IDisposable을 구현하는 개체의 Dispose 메서드에서 호출해야합니다. 이렇게하면 someones가 Dispose 메서드를 호출 할 때 GC가 finalizer를 다시 호출하지 않습니다.

참조 : http://msdn.microsoft.com/en-us/library/system.gc.suppressfinalize.aspx

+6

"반드시"해야한다고 생각합니다. "해야"하지 않습니다. - 어떤 시나리오에서는 객체 대기열에 넣기/마무리 작업의 오버 헤드를 없앨 수 있습니다. – Basic

29

당신이 종료자를 호출 할 필요가 없다, 그래서 이미 완료되었습니다 어떤 작업이 종료 자에서 수행되었을 시스템을 말하는 것입니다. 필요없는 객체에 Object.Finalize를 호출 에서 에 IDisposable.Dispose 방법은 가비지 컬렉터를 방지 에서이 메소드를 호출 할 수는 IDisposable 인터페이스를 구현

객체 : 닷넷 워드 프로세서 그것.

일반적으로 대부분의 Dispose() 메서드는 마무리 자에서 정리 될 모든 내용을 정리해야하므로 GC.SupressFinalize() 메서드를 호출 할 수 있어야합니다.

SupressFinalize는 시스템이 객체를 파이널 라이저 스레드에 대기시키는 것을 방해하지 않도록하는 최적화 기능을 제공합니다. 적절히 작성된 Dispose()/finalizer는 GC.SupressFinalize() 호출을 사용하거나 사용하지 않고 올바르게 작동해야합니다.