C#에서 가비지 컬렉터(Garbage Collector, GC)는 .NET 프레임워크의 중요한 컴포넌트로, 자동으로 메모리 관리를 수행합니다. 가비지 컬렉터는 개발자가 명시적으로 메모리를 해제하지 않아도 되도록 설계되었으며, 사용되지 않는 객체의 메모리를 자동으로 회수합니다. 이 메커니즘은 메모리 누수를 방지하고, 프로그램의 안정성과 성능을 향상시키는 데 기여합니다.
가비지 컬렉터는 "mark and sweep" 알고리즘을 기반으로 작동합니다. 주요 과정은 다음과 같습니다:
.NET의 가비지 컬렉터는 세대별 수집(Generational Collection) 방식을 사용하여 효율성을 높입니다. 객체들은 세대에 따라 분류되며, 객체의 수명이 길어질수록 높은 세대로 이동합니다. 세대는 다음과 같이 분류됩니다:
가비지 컬렉터는 편리하고 효과적인 메모리 관리를 제공하지만, 가비지 컬렉션 과정에서 애플리케이션의 실행이 일시 중단될 수 있습니다. 이러한 "Stop-the-world" 중단은 가비지 컬렉션 중 모든 애플리케이션 스레드가 일시 정지되는 현상입니다. 따라서 효율적인 메모리 사용과 객체 할당 전략은 가비지 컬렉션의 빈도와 영향을 최소화하는 데 중요합니다.
내부적으로 GC의 알고리즘은 Mark and Sweep를 기반으로 하게 되는데 그 이후의 과정이 다르게 됩니다.
.Net에서는 0~2세대까지 총 3개의 세대를 통해서 관리를 하게 됩니다.
유니티에서는 Boehm-Demers-Weiser 라는 알고리즘을 통해 GC 작업을 하게 됩니다. Mark and Sweep인것은 같으나 세대 구분이 없고 메모리 정렬도 없습니다. 때문에 19 버전 이상에서 제공하게 되는 점진적 GC 작업을 활용하거나 오브젝트 풀링 등의 기법을 활용해서 최대한 최적화를 해줘야 할 필요가 있습니다.
만일 C#에서 두 객체가 서로 참조중이라 하더라도 외부에서 참조가 없어 Mark 되지 않는다면 Sweep 단계에서 해제되게 됩니다.