퀴즈 질문 |
|
|
예상답변/설명 |
C++의 Destructor는 ~Class() {...} 같이 클래스명 앞에 ~를 붙여 선언되며, 클래스 객체가 소멸될 때 리소스를 해제하기 위해 사용된다. C++의 소멸자는 프로그램 중 delete obj1;과 같은 문장이 실행될 때 호출되며 개발자가 정확히 언제 소멸자를 실행할지를 컨트롤 할 수 있다.
C#의 Destructor는 C++와 구분하기 위해 흔히 Finalizer로 불리우며, C++와 같이 ~Class() {....} 문장을 사용한다. 하지만, 근본적으로 다른 점은 이 Finalizer가 언제 실행될 지 개발자가 알 수 없고 결정할 수도 없다는 점이다. 이는 Managed Code의 경우 .NET의 Garbage Collection 메카니즘을 사용하기 때문인데, Finalizer와 관련된 Garbage Collector(GC) 동작을 요약하면 다음과 같다.
C# 클래스에 Finalizer(Destructor) 메서드가 있으면, 해당 객체는 생성자 호출시 Finalziation Queue라고 하는 GC안의 내부 큐에 해당 객체 레퍼런스가 추가된다. 이 후 Managed Heap이 차서 Garbage Collection이 필요하게 되면, Finalization Queue에 없는 객체들은 사용중이 아니면 Garbage로 판단해서 삭제하게 되지만, Finalization Queue에 있는 객체는 이 객체 레퍼런스를 Freachable Queue라고 하는 다른 내부 큐로 이동시키게 된다. 이후, GC의 특별한 Finalization Thread가 이 Freachable Queue에서 객체를 하나씩 꺼내서 Destructor안의 코드 (컴파일러는 이를 Finalize()메서드 호출로 변경한다) 실행한다. 이렇게 모든 Finalizer 코드들이 실행되고, 다음 Garbage Collection 시기가 오면 GC는 Finalizer가 있던 객체를 이제 Garbage로 인식해서 삭제하게 된다.
[추가질문] C# 클래스에 특정 코드 없이 Destructor를 추가하면 어떤 문제가 있는가?
[A] C# 클래스에 특별한 이유없이 Destructor를 추가하면 해당 객체 혹은 이 객체가 포함하는 내부 객체들이 장기간 존속하게 되고, 객체수가 많은 경우 성능을 저하시키는 원인이 된다. 예를 들어, 배열 10000개를 만들었는데, 각 요소마다 Finalize 메서드를 호출해야 된다면 성능이 저하될 것이다.
|