참조 횟수 계산
참조 횟수 계산(Reference Counting)은 가장 고전적인 방식으로 객체마다 나를 참조하는 곳이 몇 군데인지 기록하는 카운터를 둔다.
-
원리: 누군가 참조하면 +, 참조를 끊으면 - 하며, 카운트가 0이 되면 즉시 메모리를 해제한다.
-
한계: 순환 참조(Circular Reference) 문제를 해결하지 못한다. 예시로 A가 B를 가리키고, B가 A를 가리키면 둘 다 사용하지 않아도 카운트가 0이 되지 않아 영원히 메모리에 남는다.
추적 기반 알고리즘
.NET 가비지 컬렉터가 사용하는 방식으로 루트부터 시작해서 객체의 연결 고리를 따라가는 방식이다.
-
마킹 앤 스윕(Mark And Sweep): 루트에서 시작하여 연결된 모든 객체를 방문하고 살아있음을 나타내는 비트를 체크한다. 이후 힙 전체를 선형적으로 훑으며 마킹되지 않은 객체를 메모리에서 제고한다.
- 단점: 청소 후 메모리 사이에 메모리 파편화(Fragmentation)가 발생한다.
-
마킹 앤 스윕 컴팩트(Mark And Sweep Compact): .NET 가비지 컬렉션이 관리되는 힙에서 사용하는 표준 방식이다.
Stop The World 현상
STW(Stop The World) 현상은 가비지 컬렉션 알고리즘이 실행되는 동안, 객체의 위치가 바뀌면 안되기 때문에 애플리케이션의 모든 스레드를 일시 정지시키는 현상이다.
- 목표: 이 시간을 최소화하는 것이 모든 가비지 컬렉션 알고리즘의 이상이다.
고성능 서버를 위한 알고리즘 변주
백그라운드 가비지 컬렉션과 동시성 가비지 컬렉션의 원리는 다음과 같다.
-
원리: 2세대 수집을 할 때, 모든 스레드를 멈추지 않고 애플리케이션 실행과 동시에 별도의 가비지 컬렉션 스레드에서 수집을 진행한다.
-
이점: 사용자 입장에서 프로그램이 잠시 멈춘 느낌을 주지 않는다. .NET 4.0 이후 도입되어 현재 데스크톱 및 서버 환경의 기본값이다.
워크 스테이션 가비지 컬렉션과 서버 가비지 컬렉션의 차이는 다음과 같다.
-
워크 스테이션: 일반적인 PC용 메모리 절약과 반응성에 초점을 맞춘다.
-
서버: 멀티 코어 서버용 CPU 코어 당 하나씩 가비지 컬렉션 전용 스레드와 힙을 할당한다. 병렬 처리가 가능하므로 수집 속도가 압도적이지만, 메모리 사용량이 더 많다.
LOH 전용 알고리즘
85,000 바이트 이상의 객체는 이동 비용이 너무 크다. 따라서 LOH(Large Object Heap)은 기본적으로 마킹 앤 스윕 알고리즘만 수행하고 압착 즉, 컴팩트는 실행하지 않는다. 하지만 이로 인해 메모리 파편화가 발생하여 OutOfMemoryException 예외가 발생할 수 있다. .NET 4.5.1 이후 GCSetting.LargObjectHeapCompactionMode 설정을 통해 명시적으로 LOH 압착을 명령할 수 있게 되었다.