Software Development/C#

[Effective C#] C# 가비지 컬렉터(Garbage Collector) 기초 / finalizer 이해하기

huiyu 2020. 12. 28. 19:10

가비지 컬렉터(Garbage Collector, GC)

자동 메모리 관리자, 애플리케이션의 메모리 할당 및 해제를 관리한다. 즉 개발자는 메모리 관리를 위한 코드를 작성할 필요가 없다. 메모리 누수, 댕글링 포인터(dangling pointer), 초기화 되지 않은 포인터 등의 기타 메모리 관련 문제를 개발자가 직접 다루지 않게 된다.
 * dangling pointer : 유효한 곳을 가르키고 있지 않는 포인터

-관리되지 않는 리소스(Unmanaged Resource, 비관리 리소스)의 경우엔 개발자가 직접 관리해야 하며, 이벤트 핸들러, 델리게이트 등도 잘못 사용하면 이를 참조하고 있는 객체가 불필요하게 메모리에 남게 되므로 사용에 유의해야 한다.
->그럼에도 Garbage Collector가 메모리를 전반적으로 관리해주기 때문에 메모리 관리를 개발자가 책임져야 하는 환경에 비해 상대적으로 구조를 단순하게 유지할 수 있다.

가비지 컬렉터의 콤팩트(Compact) 작업

- 콤팩트 작업이란, 사용중인 객체들을 한쪽으로 옮겨서 조각난 가용 메모리를 단일의 큰 메모리 공간으로 만드는 과정.
- 가비지 컬렉터는 사용되지 않는 객체를 제거할 뿐만 아니라, 사용중인 객체들을 옮겨서 조각난 가용 메모리를 단일의 큰 메모리로 만든다.

 이러한 메모리 관리는 가비지 컬렉터가 자동으로 관리하게 된다. 그러나 이 외의 비관리 리소스는 개발자가 직접 관리해야 한다. .Net Framework는 비관리 리소스에 대해서도 개발자가 쉽게 관리할 수 있도록 'finalizer'와 'IDisposable' 인터페이스를 제공하고 있다.
* finalizer는 단점이 많기 때문에 이보단 IDisposable을 이용해 unmanaged 리소스가 빠르게 해제될 수 있도록 구현하는 것이 좋다.

finalizer(destructor)

종료자 또는 소멸자. 객체가 가비지 컬렉터에 의해 제거 될 때에만 호출되며 명시적으로 호출할 수 없다. 최종적으로 코드를 정리 하는데 사용할 수 있다.

 - finalizer는 구조체에는 정의할 수 없으며, 클래스에서만 사용
 - 클래스에는 하나의 finalizer만 있을 수 있다.
 - finalizer는 상속하거나 오버로드할 수 없다.
 - finalizer를 명시적으로 호출할 수 없고, 가비지 컬렉터 대상이 됐을 때 자동으로 호출된다.
 - finalizer는 한정자를 사용하거나 매개 변수를 갖을 수 없다.

* finalizer를 가지고 있는 객체는 가비지로 간주된 이후에도 꽤 긴 시간 메모리를 점유하게 된다. 사용자가 구현한 finalizer는 상당한 시간이 경과한 후 가비지 컬렉터에 의해 호출되며, 정확히 어느 시점에 불릴지 알 수 없다.
 -> finalizer는 가비지 컬렉터에 의해 언젠가 호출되지만 정확히 불리는 시점은 알 수 없다.

** finalizer의 사용시 유의사항
 1) finalizer사용시 성능 이슈
  - finalizer를 포함한 객체의 경우엔 finalizer를 호출해야하기 때문에 가비지로 판단된 이후에도 즉시 메모리에서 해제하지 않는다. 그렇기 때문에 finalizer를 포함하고 있는 객체를 사용하면 가비지 컬렉트 과정이 더 길어진다. 
  **가비지 컬렉터는 객체에 대한 참조를 다른 큐에 삽입하여 나중에 finalize가 호출될 수 있도록 준비하는데 이 과정에서 finalizer가 없는 객체는 메모리로부터 즉각 제거된다. 그러나 finalizer가 있는 객체는 다른 큐에 넣어두었다 일정시간이 지난뒤 객체를 꺼낸 후 finalizer를 호출하며 메모리를 해제한다. 

 2) finalizer를 호출하는 쓰레드는 별도의 finalizer 쓰레드에서 호출되기 때문에 finalizer에서 lock을 해제하게 되면 문제가 발생할 수 있다. 

 

Dispose 패턴 사용

**finalizer는 응용프로그램의 성능에 영향을 미치므로 finalizer보단 IDisposable 인터페이스를 구현하여 가바지 컬렉트 과정이 지연되는 것을 방지해야 한다.

 

[참고링크]
* Effective C# 2장 .NET 리소스 관리 : 아이템11-.NET 리소스 관리에 대한 이해
* finalizer : docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/destructors

 

Finalizers - C# Programming Guide

Finalizers in C#, which are also called destructors, perform any necessary final clean-up when a class instance is being collected by the garbage collector.

docs.microsoft.com

* garbage collector : docs.microsoft.com/en-us/dotnet/standard/garbage-collection/fundamentals

 

Fundamentals of garbage collection

Learn how the garbage collector works and how it can be configured for optimum performance.

docs.microsoft.com

* Finalizer 기초 : www.simpleisbest.net/post/2011/05/12/Finalizer-Usage-Pattern.aspx

 

SimpleIsBest.NET | Finalizer 사용 시 주의 사항들

닷넷 플랫폼 환경은 메모리 회수를 가비지 컬렉션에 의존하고 있습니다. 그래서 파일, 데이터베이스 연결과 같은 시스템 자원을 해제하기 위해 기존 C/C++과 다른 방식을 취합니다. 그 중 하나가

www.simpleisbest.net

 

728x90