다음 본문은 도서 이펙티브 C# (빌 와그너)에서 나오는 주제를 다룹니다.
2021.04.13 - [기술 면접용 질문들/운영체제 관련] - 가비지 컬렉션(Garbage Collection)
가비지 콜렉터
- 메모리 누수, 유효한 객체를 가리키고 있지 않은 포인터, 초기화되지 않는 포인터 등의 문제를 자동화해준다.
- 메모리를 신경 쓸 필요가 없어지기 때문에 프로그램 구조를 단순하게 유지할 수 있다.
- 응용 프로그램 내의 최상위 객체로부터 참조 트리를 구성하여 도달 불가능한 객체를 가비지로 간주한다.
콤팩트 작업
- 사용중인 객체들을 옮겨 조각단 가용 메모리를 단일의 큰 메모리 공간으로 만드는 과정
비관리 리소스
- 힙에 대한 메모리 관리는 가비지 수집기가 책임을 지지만, 비관리 리소스는 여전히 개발자가 관리해야 한다.
- 비관리 리소스(COM 객체, 시스템 객체 등)는 개발자가 직접 관리해야 한다.
- 비관리 리소스의 관리를 위해 finalizer와 IDisposable 인터페이스가 제공된다.
종료자 (finalizer)
class Car
{
~Car() // finalizer
{
// cleanup statements...
}
}
- 수집되기 전 가비지 콜렉터에 의해 호출된다.
- 할당된 비관리 리소스를 최종적으로 해제할 수 있는 유일한 방법.
- 그러나 단점이 많아서 최대한 사용하지 않도록 구조를 설계하는 것이 현명하다.
- 해당 객체가 가비지로 간주된 이후에도 긴 시간을 메모리를 점유하며, 어느 시점에 호출될지 알 수 없다.
C++에서의 리소스 해제 구문은 예외가 발생하는 경우에도 동작하지만, C#에서는 제대로 동작하지 않거나 다른 방식으로 동작한다. 때문에 C#에서는 원하는 시점에 정확히 객체를 해제하는 기능을 제공하지 않는다.
- finalizer를 포함하는 객체는 finalizer를 호출해야 하기 때문에 즉시 메모리를 해제하지 못하며,
가비지 스레드에서는 직접 finalizer를 호출하지 못하니 호출될 수 있도록 준비를 수행한다.
- 가비지 컬렉터의 세대별 수집 모델에 따라, 즉시 해제되지 못한 객체는 다음 세대가 되고, 세대가 높아질수록 가비지 검사 간격도 넓어지기 때문에 예상보다도 훨씬 오래 메모리에 남아있게 된다.
- 즉, 성능이 나빠진다.
결론
- .NET환경에서 비관리 리소스를 해제할 때는 finalizer가 아니라 IDisposable 인터페이스와 표준 Dispose패턴을 사용하자.
'🌍 C# Study > 이펙티브 C#' 카테고리의 다른 글
[13] 정적 클래스 멤버를 올바르게 초기화하라 (0) | 2021.04.25 |
---|---|
[12] 할당 구문보다 멤버 초기화 구문이 좋다 (0) | 2021.04.25 |
[10] 베이스 클래스가 업그레이드된 경우에만 new 한정자를 사용하라 (0) | 2021.04.23 |
[09] 박싱과 언박싱을 최소화하라 (0) | 2021.04.23 |
[08] 이벤트 호출 시에는 null 조건 연산자를 사용하라 (0) | 2021.04.23 |