04
25
다음 본문은 도서 이펙티브 C# (빌 와그너)에서 나오는 주제를 다룹니다.

2021.04.13 - [기술 면접용 질문들/운영체제 관련] - 가비지 컬렉션(Garbage Collection)

 

 

가비지 콜렉터

 - 메모리 누수, 유효한 객체를 가리키고 있지 않은 포인터, 초기화되지 않는 포인터 등의 문제를 자동화해준다.

 - 메모리를 신경 쓸 필요가 없어지기 때문에 프로그램 구조를 단순하게 유지할 수 있다.

 - 응용 프로그램 내의 최상위 객체로부터 참조 트리를 구성하여 도달 불가능한 객체를 가비지로 간주한다.

 

콤팩트 작업

 - 사용중인 객체들을 옮겨 조각단 가용 메모리를 단일의 큰 메모리 공간으로 만드는 과정

 

비관리 리소스

 - 힙에 대한 메모리 관리는 가비지 수집기가 책임을 지지만, 비관리 리소스는 여전히 개발자가 관리해야 한다.

 - 비관리 리소스(COM 객체, 시스템 객체 등)는 개발자가 직접 관리해야 한다.

 - 비관리 리소스의 관리를 위해 finalizerIDisposable 인터페이스가 제공된다.

 

종료자 (finalizer)

class Car
{
    ~Car()  // finalizer
    {
        // cleanup statements...
    }
}

 - 수집되기 전 가비지 콜렉터에 의해 호출된다.

 - 할당된 비관리 리소스를 최종적으로 해제할 수 있는 유일한 방법.

 - 그러나 단점이 많아서 최대한 사용하지 않도록 구조를 설계하는 것이 현명하다.

 - 해당 객체가 가비지로 간주된 이후에도 긴 시간을 메모리를 점유하며, 어느 시점에 호출될지 알 수 없다.

C++에서의 리소스 해제 구문은 예외가 발생하는 경우에도 동작하지만, C#에서는 제대로 동작하지 않거나 다른 방식으로 동작한다. 때문에 C#에서는 원하는 시점에 정확히 객체를 해제하는 기능을 제공하지 않는다.

 - finalizer를 포함하는 객체는 finalizer를 호출해야 하기 때문에 즉시 메모리를 해제하지 못하며,

   가비지 스레드에서는 직접 finalizer를 호출하지 못하니 호출될 수 있도록 준비를 수행한다.

 - 가비지 컬렉터의 세대별 수집 모델에 따라, 즉시 해제되지 못한 객체는 다음 세대가 되고, 세대가 높아질수록 가비지 검사 간격도 넓어지기 때문에 예상보다도 훨씬 오래 메모리에 남아있게 된다. 

 - 즉, 성능이 나빠진다.

 

결론

 - .NET환경에서 비관리 리소스를 해제할 때는 finalizer가 아니라 IDisposable 인터페이스와 표준 Dispose패턴을 사용하자. 

 

 

 

COMMENT