Finalize 메서드 및 소멸자
업데이트: 2007년 11월
.NET Framework의 가비지 수집기는 응용 프로그램에서 만드는 대부분의 개체에 대해 메모리 관리에 필요한 모든 작업을 암시적으로 수행합니다. 그러나 관리되지 않는 리소스를 캡슐화하는 개체를 만든 경우에는, 응용 프로그램에서 더 이상 사용하지 않는 관리되지 않는 리소스를 명시적으로 해제해야 합니다. 가장 일반적인 관리되지 않는 리소스는 운영 체제 리소스(예: 파일, 창 또는 네트워크 연결)를 래핑하는 개체입니다. 가비지 수집기는 관리되지 않는 리소스를 캡슐화하는 개체의 수명을 추적할 수 있지만 해당 리소스를 정리하는 데 필요한 정보는 갖고 있지 않습니다. .NET Framework에서는 이러한 개체 형식에 사용할 수 있는 Object.Finalize 메서드를 제공하는데, 이 메서드는 개체에서 사용한 메모리를 가비지 수집기가 회수했을 때 개체가 관리되지 않는 리소스를 제대로 정리할 수 있도록 합니다. 기본적으로, Finalize 메서드는 아무것도 수행하지 않습니다. 가비지 수집기가 개체에 대한 정리 작업을 수행한 후에 해당 개체의 메모리를 회수하도록 하려면 클래스의 Finalize 메서드를 재정의해야 합니다.
참고: |
---|
Finalize 메서드를 C#에서 구현하려면 소멸자 구문을 사용해야 합니다. .NET Framework 버전 2.0의 Visual C++에서는 Destructors and Finalizers in Visual C++에 설명된 대로 Finalize 메서드 구현을 위한 구문이 제공됩니다. .NET Framework 버전 1.0 및 1.1의 경우 Visual C++에서는 C#과 마찬가지로 Finalize 메서드에 소멸자 구문을 사용했습니다. |
가비지 수집기는 종료 큐라고 하는 내부 구조를 사용하여 Finalize 메서드가 있는 개체를 모두 추적합니다. 응용 프로그램에서 Finalize 메서드가 있는 개체를 만들 때마다 가비지 수집기는 해당 개체를 가리키는 엔트리(항목)를 종료 큐에 추가합니다. 종료 큐에는 관리되는 힙에 있는 개체 중 가비지 수집기가 메모리를 회수하기 전에 종료 코드가 호출되어야 하는 모든 개체에 대한 엔트리가 들어 있습니다.
참고: |
---|
GC.KeepAlive 메서드의 코드 예제에서는 적극적인 가비지 수집으로 인해, 회수된 개체의 멤버가 아직 실행되는 동안 종료자가 실행되게 할 수 있는 방법과 KeepAlive 메서드를 사용하여 이를 방지하는 방법을 보여 줍니다. |
응용 프로그램에서 예외를 처리할 수 없으며 예외로 인해 응용 프로그램이 종료될 수 있기 때문에 Finalize 메서드에서 예외를 throw하지 않아야 합니다.
Finalize 메서드나 소멸자를 구현하면 성능이 저하될 수 있으므로 꼭 필요할 경우에만 사용해야 합니다. Finalize 메서드가 있는 개체에 할당된 메모리를 회수하는 데는 가비지 수집을 두 번 이상 해야 합니다. 가비지 수집기는 종료자가 없고 액세스할 수 없는 개체의 메모리를 회수하는데, 이때 종료자가 있고 액세스할 수 없는 개체는 수집하지 않고 대신, 이들 개체의 엔트리를 종료 큐에서 제거하여 종료될 준비가 된 개체 목록에 추가합니다. 이 목록의 엔트리는 관리되는 힙에 있는, 종료 코드가 호출될 개체를 가리킵니다. 가비지 수집기에서는 이 목록에 있는 개체에 대해 Finalize 메서드를 호출하여 목록에서 항목을 제거합니다. 이 작업이 완료되면, 종료될 준비가 된 개체 목록의 엔트리에서 더 이상 개체를 가리키지 않기 때문에, 이후에 실행되는 가비지 수집기는 종료된 이들 개체를 가비지로 처리합니다. 개체의 메모리는 이 두 번째 가비지 수집 시에 회수됩니다.