C#에는 공용언어런타임인 CLR에 가비지 컬렉터가 있다. 그래서 개발자가
사용하는 메모리를 모두 가비지 컬렉터에서 알아서 관리해줄거라 생각하는데
사실 아니다. 파일 IO, DB, Connection 등 이러한 것들은 CLR에 의해 관리되지 않는다.
그래서 그에맞는 기능들을 사용해야 하는데 이것에 대해 설명하고자 한다.
1. Finalizer
Finalizer 란 "종료자" 라는 뜻으로 위에서 말한 IO, DB, Connection 등을 직접 해제할 수
있는 기능이다.
Finalizer는 이러한 형식으로 작성하여 사용된다.
2. Finalizer의 단점
Finalizer는 가비지 컬렉터가 가비지라고 판단한 시점부터 문제가 생긴다.
일반적인 메모리라면 즉시 해제되지만 Finalizer의 경우 이를 호출한 다음에
메모리를 해제하기 때문에 메모리 공간을 즉시 해제하지 못한다는 단점이 있다.
요약하자면 Finalizer가 포함된 객체가 가비지로 판단 시 메모리가 즉시 제거되지 않고
큐에 삽입된다. -> Finalizer가 포함되지 않는 객체를 제거한다. -> 다시 가비지를 수집하여
Finalizer를 호출한다.
이러한 과정을 거쳐야 하기 때문에 복잡한 가비지 수행과정에 있어서 오랜시간 메모리를
점유하고 있는 Finalizer포함 객체가 큰 문제가 되는 것이다.
심지어 Finalizer는 사용자가 호출하는 것이 아닌 가비지 컬렉터가 호출하는 구조여서
언제 호출 될지 모른다는 것도 큰 단점이 된다.
3. 해결법
Finalizer는 안좋은 방법이긴 하나 특정한 파일의 메모리를 해제하려면 어쩔 수 없이
사용해야 한다. 하지만 이를 해결해줄 방법 Dispose 패턴이 있다.
Finalizer의 단점을 보면 메모리 점유 시간이 길고 암시적인 호출이 큰 문제다.
그러면 명시적으로 호출할 수 있고 Finalizer를 따로 관리 해주면 해결될 것이다.
이를 가능하게 해주는 것이 Dispose패턴인데 가비지 컬렉터에 Finalizer가
호출되기 전에 사용자가 직접 해제 해주는 방법이다.
그러면 Finalizer 객체가 오랜시간 점유하고 있는 단점과 사용자가 원하는
시기에 호출이 가능하여 암시적 호출로 인하여 생기는 단점을 해결해줄 수 있다.
하지만 여기서 주의점은 만약 Dispose 패턴이 실행되지 않았을 경우 Finalizer 기능이
실행될 수 있게 만들어야 한다.
요약
가비지 컬렉터를 회피하기 위한 방법 중 하나는 Dispose패턴이 있다.
가비지 컬렉터에서 관리되지 않는 리소스는 Finalizer를 사용하여 해결할 수 있는데
Finalizer는 가비지컬렉터의 암시적호출과 긴 시간 메모리 점유라는 단점이 있다. 하지만 Dispose패턴을
사용하면 명시적호출로 메모리 관리가 가능해져 가비지 컬렉터로 인한 성능저하를 회피할 수 있다.
'TIL > C#' 카테고리의 다른 글
[C#] 박싱과 언박싱 (0) | 2023.11.01 |
---|---|
[C#] 가비지 컬렉션(Garbage Collection) (0) | 2023.10.31 |
[C#] 가비지 컬렉터 (0) | 2023.10.27 |
[C#] Struct와 Class의 차이점 (0) | 2023.10.26 |
[C#] 접근제한자의 종류와 차이점 (0) | 2023.10.25 |