본문으로 건너뛰기
목록으로

GC 종류 쉽게 이해하기 — 특징과 상황별 선택 기준

Johny Cho
Software Engineer @ Kurly

가비지 컬렉터(GC)는 앱이 안 쓰는 객체를 대신 정리해 주는 일입니다. 앱을 달리는 자동차에 비유하면 GC는 그 차를 세차하는 셈이라, 세차 방식이 여러 가지고 "차를 얼마나 세우느냐 vs 얼마나 빨리 세차하느냐"가 성능을 좌우합니다. 겁먹을 필요 없이 딱 하나의 축만 기억하면 됩니다 — "세차를 빠르게 끝내기(처리량)" vs "세차하느라 차를 세우는 시간 줄이기(정지 시간)". 이 글은 이 축을 기준으로 GC 종류를 최대한 쉽게 풀어 봅니다. (실제 튜닝 상황은 JVM 튜닝 시나리오 참고)

GC가 하는 일 — 1분 복습

객체는 대부분 금방 안 쓰게 됩니다(잠깐 쓰고 버려지는 임시 객체가 많음). GC는 이 성질을 이용해 메모리를 두 구역으로 나눠 관리합니다.

  • Young 세차(Minor GC) — 막 생긴 부분을 자주, 빠르게 세차. 대부분 여기서 끝.
  • Old 세차(Major/Full GC) — 오래 남은 부분까지 가끔 크게 세차. 무겁고 느림.

"오래된 부분까지 크게 하는 Full GC"가 길어질 때가 문제라, GC 종류마다 이걸 어떻게 다루느냐가 갈립니다. 세차하려고 달리던 차(앱)를 잠깐 세우는 것stop-the-world(STW) 라고 부릅니다.

핵심 축 하나 — 처리량 vs 정지 시간

GC를 고르는 기준은 사실상 이 둘의 저울질입니다.

  • 처리량(throughput) — 같은 시간에 앱이 실제 일한 비율. GC에 시간을 적게 뺏길수록 높음.
  • 정지 시간(pause) — 세차하느라 차(앱)가 멈추는 시간. 짧을수록 사용자가 느끼는 지연이 작음.

둘 다 최고인 방식은 없습니다 — 처리량을 노리면 정지가 좀 길고, 정지를 줄이면 처리량을 약간 내줍니다. 그래서 "내 서비스가 무엇을 더 중요하게 여기나"가 선택의 출발점입니다.

종류별로 — 어떻게 세차하나

Serial GC — 정비공 한 명이 차를 세워 놓고 혼자 세차합니다.

  • 특징: 단순·가벼움. 힙이 작으면 충분. 힙이 크면 멈춤이 길어짐.
  • 언제: 아주 작은 앱, CLI 도구, 메모리 적은 환경.
  • 플래그: -XX:+UseSerialGC

Parallel GC — 정비공 여러 명이 차를 세워 놓고 한꺼번에 빠르게 세차합니다.

  • 특징: 멈추긴 하지만 총 처리량이 가장 좋음. 대신 한 번 멈추면 길 수 있음.
  • 언제: 지연은 상관없고 처리량이 중요한 배치·백그라운드 작업.
  • 플래그: -XX:+UseParallelGC

G1 GC (기본값) — 차를 여러 구역으로 나눠 더러운 곳부터 조금씩 세차합니다.

  • 특징: 정지 시간과 처리량의 균형. "정지를 이 정도로 맞춰 줘"라는 목표를 줄 수 있음.
  • 언제: 대부분의 일반 서비스(고민되면 이걸로).
  • 플래그: -XX:+UseG1GC (JDK 9부터 기본), 목표 정지 -XX:MaxGCPauseMillis=100

ZGC — 차를 거의 세우지 않고 달리는 중에 세차합니다.

  • 특징: 힙이 수십~수백 GB로 커도 정지가 수 ms 이하. 최신 저지연 방식.
  • 언제: 정지 시간 목표(SLO)가 빡빡한 대용량·저지연 서비스.
  • 플래그: -XX:+UseZGC (JDK 21부터 세대 구분 방식이 기본)

Shenandoah — ZGC처럼 차를 거의 세우지 않는 저지연 방식(OpenJDK 계열).

  • 특징: 힙 크기와 무관하게 짧은 정지. ZGC의 대안.
  • 언제: 저지연이 필요하고 OpenJDK 배포판을 쓸 때.
  • 플래그: -XX:+UseShenandoahGC

Epsilon아예 세차하지 않는 방식(세차 없음).

  • 특징: 메모리가 차면 그냥 종료. 오직 성능 측정·아주 짧게 살다 죽는 작업용.
  • 언제: 벤치마크·실험. 일반 서비스엔 쓰지 않음.
  • 플래그: -XX:+UseEpsilonGC

상황별로 무엇을 고를까

상황추천
일반 웹 서비스(고민되면)G1정지·처리량 균형, 기본값
야간 배치·대량 처리(지연 무관)Parallel총 처리량 최고
응답 지연 SLO가 빡빡함ZGC / Shenandoah정지 수 ms
대용량 힙(수십 GB+)인데 정지 싫음ZGC힙 커도 짧은 정지
아주 작은 앱·CLISerial단순·가벼움
성능 측정·초단명 작업Epsilon세차 오버헤드 0

간단한 결정 흐름으로 보면 이렇습니다.

버전·기본값 주의

  • JDK 9부터 기본 GC는 G1입니다(그 이전 기본은 Parallel). 특별한 이유 없이 옛 플래그로 Parallel을 강제하고 있지 않은지 확인하세요.
  • ZGC/Shenandoah는 비교적 최신이라 JDK 버전과 배포판(OpenJDK 등)을 확인해야 합니다.
  • 대부분은 기본 G1로 충분하고, "정지가 목표를 깬다"가 지표로 확인될 때만 ZGC/Shenandoah로 옮기면 됩니다. 지표 보는 법은 서버 지표 읽기.

정리

  • GC 선택은 처리량 vs 정지 시간 저울질 하나로 요약된다.
  • Serial(작은 앱)·Parallel(처리량 배치)·G1(균형·기본)·ZGC/Shenandoah(저지연)·Epsilon(측정용).
  • 고민되면 G1, 지연이 중요하면 ZGC, 배치면 Parallel.
  • 먼저 기본값으로 두고, 문제를 지표로 확인한 뒤 바꾸는 순서가 정답입니다.

GC가 트래픽에 밀려 무너지는 양상은 트래픽이 늘면 어디서 깨지나, 누수로 인한 잦은 Full GC는 힙 덤프 분석을 함께 보세요.

용어 한 줄 정리

용어쉬운 뜻
Young / Old막 생긴 객체 구역 / 오래 살아남은 구역
Minor GCYoung을 자주·빠르게 세차
Major/Full GCOld까지 크게 세차(무겁고 느림)
stop-the-world세차하느라 차(앱)를 잠깐 멈추는 구간
처리량같은 시간에 앱이 실제 일한 비율
정지 시간세차로 차(앱)가 멈추는 시간(짧을수록 좋음)