← 문제로

14. .NET GC 세대·LOH·Server vs Workstation GC

난이도 상
내 리뷰 · C#
해설 · C#

해설 — .NET GC 세대·LOH·Server vs Workstation GC

난이도: 상

요약

.NET GC는 "대부분의 객체는 금방 죽는다"는 세대 가설에 기반한 세대별 수집기다. 작은 객체는 gen0에서 태어나 살아남으면 gen1→gen2로 승격되고, 85,000바이트 이상의 큰 객체는 별도의 대형 객체 힙(LOH) 에 할당되어 gen2로 취급된다. 짧은 수명 객체를 대량 생성하면 gen0 수집이 잦아지고, 이 압박을 Server GC(코어별 다중 힙)·백그라운드 GC(동시 gen2 수집)가 완화한다.

예측 출력

(1) 0       // small: 막 할당된 작은 객체 → gen0
(2) 2       // large: 100,000B ≥ 85,000B → LOH → GetGeneration은 2를 보고
(3) True    // 100만 번의 gen0 할당으로 gen0 수집이 여러 번 발생 → CollectionCount(0) 증가
(4) 2       // GC.Collect()는 전체(gen2) 수집 → 살아남은 small이 gen2로 승격
  • (4)는 런타임/버전에 따라 정확한 세대가 다를 수 있으나, "전체 수집 후 생존자는 상위 세대로 승격된다"는 핵심은 동일하다.

단계별 내부 동작

  1. 할당(gen0): 작은 객체는 gen0 영역에 포인터 범프(bump pointer)로 매우 싸게 할당된다(거의 스택 push 수준).
  2. gen0 수집: gen0가 차면 gen0만 수집한다. 가설대로 대부분 죽었으면 살아남은 소수만 gen1로 승격(복사/압축). 짧고 빈번한 수집이라 일시정지가 짧다.
  3. 승격(gen1→gen2): gen1에서도 살아남으면 gen2로. gen2 수집(full GC)은 전체 힙을 보므로 비싸고 일시정지가 길다 — 장수명 객체가 많을수록 gen2가 커지고 full GC가 비싸진다.
  4. LOH: 85,000바이트 이상 객체는 LOH에 할당된다. 큰 객체를 gen0/1로 자주 복사·압축하면 비용이 크기 때문에, LOH는 압축을 기본적으로 하지 않고(주소 고정) gen2와 함께(=full GC 때만) 수집된다. 그래서 GetGeneration이 2를 돌려준다.
  5. Server vs Workstation:
    • Workstation GC(클라이언트 기본): 힙 하나. (동시/백그라운드 모드면) 별도 GC 스레드.
    • Server GC: 논리 코어마다 힙과 전용 GC 스레드를 둬 수집을 병렬화 → 높은 처리량(서버에 적합). 대신 메모리 사용↑.
    • 백그라운드 GC: gen2(full) 수집을 애플리케이션과 동시에 진행해 긴 일시정지를 줄인다(gen0/1는 여전히 짧게 멈춤).

흔한 오해·함정

  • "큰 배열은 일찍 수집된다"는 착각: LOH는 gen2라 full GC 때만 회수된다. 큰 임시 버퍼를 자주 만들면 LOH 단편화 + 잦은 full GC로 틱 지연(스파이크)이 생긴다 → ArrayPool<T>/풀링으로 재사용.
  • LOH 단편화: 압축을 안 하므로 빈 구멍이 쌓인다. 필요 시 GCSettings.LargeObjectHeapCompactionMode로 1회 압축 가능(비싸므로 가끔만).
  • 경계는 85,000바이트(객체 단위; 배열 헤더 포함 ~). byte[84_900]은 SOH, byte[100_000]은 LOH.
  • 게임 서버 틱 지연의 주범: 매 틱 수많은 작은 할당 → gen0 GC가 틱 루프 중에 끼어들어 지연 지터. 해법은 할당 줄이기(struct·Span·풀링), Server+백그라운드 GC, 그리고 핫패스에서 LINQ/람다 클로저 할당 회피.

면접 포인트

  • 세대 가설과 gen0/1/2의 비용 구조: gen0는 싸고 잦고 짧다, gen2(full)는 비싸고 길다. 목표는 "객체를 gen0에서 죽이기".
  • LOH 경계(85,000B)와 LOH가 gen2 취급·비압축인 이유, 그리고 그로 인한 단편화/지연 문제와 ArrayPool 해법.
  • Workstation vs Server GC(코어별 힙)와 백그라운드 GC(동시 gen2)의 차이, 그리고 지연에 민감한 게임 서버에서의 선택 기준.