CS Fundamentals

가비지 컬렉션에 대해서 설명해주세요

Reference Counting부터 Mark-and-Sweep, 세대별 GC, JVM의 G1·ZGC까지. 면접에서 자주 묻는 GC의 핵심 개념을 인터랙티브 시각화로 체험하며 완벽히 준비합니다.

2026년 3월 15일 · 약 12분 읽기

Q. "Java의 가비지 컬렉션이 무엇인지 설명하고, JVM에서 어떤 방식으로 동작하는지 말씀해주세요."

예상 꼬리질문

답변 가이드

"가비지 컬렉션은 프로그램이 더 이상 사용하지 않는 메모리를 런타임이 자동으로 회수하는 메커니즘입니다."

"GC는 GC Root에서 참조 체인을 따라 도달할 수 없는 객체를 가비지로 판단합니다. 대표적인 알고리즘으로 Reference Counting과 Mark-and-Sweep이 있고, JVM은 Mark-and-Sweep 기반의 세대별 GC를 사용합니다."

"세대별 GC는 '대부분의 객체는 금방 죽는다'는 관찰에 기반하여 Young/Old Generation을 분리하고, 최신 GC인 G1과 ZGC는 STW(Stop-The-World) 시간을 수 ms 이하로 줄였습니다."

면접에서 "GC를 설명해주세요"라는 질문을 받으면, 단순히 "메모리를 자동 해제한다"고만 답하기 쉽습니다. 하지만 면접관이 정말 듣고 싶은 건 어떤 기준으로 해제 대상을 결정하는지, 어떤 알고리즘이 쓰이는지, 실무에서 왜 GC 튜닝이 필요한지입니다.

이 아티클에서는 면접의 꼬리질문 흐름을 따라가며, 각 개념을 직접 만져볼 수 있는 시각화로 체험합니다. 텍스트로 외우는 것보다 훨씬 오래 기억에 남을 거예요.


1. 도달 가능성 — GC의 판단 기준

꼬리질문: "GC가 객체를 쓰레기로 판단하는 기준이 뭔가요?"

GC가 객체를 "쓰레기"로 판단하는 유일한 기준은 도달 가능성(Reachability)입니다. 스택 변수, 정적 변수 등 GC Root에서 참조 체인을 따라갔을 때 닿을 수 없는 객체가 가비지입니다.

메모리가 얼마나 남았는지, 마지막으로 사용된 지 얼마나 됐는지는 관계없습니다. 오직 "루트에서 참조 체인을 통해 닿을 수 있는가"만이 기준입니다.

아래에서 참조를 끊어가며 어떤 객체가 가비지가 되는지 직접 확인해 보세요.

도달 가능성 탐색기

참조를 끊어 가비지가 어떻게 발생하는지 직접 확인해 보세요.

GC Root
A
B
C
D
E
F
GC Root
살아있는 객체
가비지 (도달 불가)
4
살아있는 객체
2
가비지
0
회수됨

2. 알고리즘 비교 — Reference Counting vs Mark-and-Sweep

꼬리질문: "Reference Counting과 Mark-and-Sweep의 차이를 설명해주세요"

Reference Counting은 각 객체에 자신을 가리키는 참조 수를 저장합니다. 카운트가 0이 되면 즉시 해제합니다. 빠르고 STW가 없다는 장점이 있지만, A→B→A처럼 순환 참조가 생기면 카운트가 절대 0이 되지 않아 메모리 누수가 발생합니다.

Mark-and-Sweep은 GC Root에서 그래프를 탐색해 닿는 객체에 표시를 남기고(Mark), 표시 없는 객체를 전부 회수합니다(Sweep). 순환 참조도 처리되지만, Mark·Sweep 동안 앱이 멈추는 STW가 발생합니다.

두 알고리즘을 전환하며 동작 차이를 비교해 보세요.

GC 알고리즘 비교

두 알고리즘을 전환하며 순환 참조 처리 방식의 차이를 확인해 보세요.

A와 B는 서로를 참조합니다(순환 참조). root 참조를 모두 제거해도 refCount가 0이 되지 않습니다.

root
GC Root
Aref=2
Bref=2
Cref=1
순환 참조: A.ref=B, B.ref=A — root 참조를 끊어도 A, B의 refCount는 1로 유지됩니다.
> 초기 상태: 모든 객체 살아있음
Reference Counting
+ 즉시 해제, STW 없음
- 순환 참조 해결 불가
Mark-and-Sweep
+ 순환 참조 처리 가능
- STW 발생

3. 세대별 GC — 대부분의 객체는 금방 죽는다

꼬리질문: "세대별 GC는 왜 필요한가요?"

현대 GC는 한 가지 관찰에 기반합니다. "대부분의 객체는 생성 직후 짧은 시간 안에 죽는다(Weak Generational Hypothesis)."

JVM 힙을 Young Generation(Eden + Survivor)Old Generation으로 나눠, 자주 죽는 Young Gen은 빠르게(Minor GC), 오래 살아남은 Old Gen은 따로 관리합니다. Old Gen이 꽉 차면 Full GC가 발생하는데, 이것이 서비스 지연의 주요 원인입니다.

새 객체를 추가하고 Minor GC를 실행해 Eden → Survivor → Old Gen 흐름을 직접 체험해 보세요.

세대별 GC 시뮬레이터

새 객체를 Eden에 추가하고 Minor GC를 실행해 보세요. 숫자(a0)는 age입니다. age 3 이상이면 Old Gen으로 승격됩니다.

Young Generation
Eden
비어있음
Survivor S0
비어있음
Survivor S1
비어있음
Old Generation (age ≥ 3에서 승격)
Tenured
비어있음
대기 중 — 새 객체를 추가하거나 Minor GC를 실행하세요.
살아있는 객체
가비지 (죽은 객체)
Old Gen 승격
Minor GC 실행 횟수: 0

4. STW와 현대 GC — 멈춤을 얼마나 줄일 수 있나

꼬리질문: "STW가 뭔지, 그리고 최신 GC는 이걸 어떻게 해결하나요?"

STW(Stop-The-World)는 GC가 힙을 분석하는 동안 모든 애플리케이션 스레드를 일시 정지시키는 현상입니다. 사용자는 이 시간 동안 응답 없음을 경험합니다.

초기 GC는 전 과정이 STW였지만, 현대 GC는 대부분의 작업을 애플리케이션과 동시에(Concurrent) 수행하고 꼭 필요한 순간만 짧게 멈춥니다.

  • Serial GC: 전체 GC가 단일 스레드 STW (~250ms)
  • G1 GC: 힙을 Region으로 분할, 예측 가능한 pause 목표 설정 (~50ms)
  • ZGC: STW를 1ms 미만으로 단축 (착색 포인터 기술 활용)

각 GC별 STW 구간과 동시 처리 구간을 타임라인에서 비교해 보세요.

GC별 STW 비교

GC 방식을 선택하고 타임라인을 재생해 STW 구간(빨간색)과 동시 처리 구간(초록색)을 비교해 보세요.

Serial GC
~250ms
pause
처리량 ~90%
G1 GC
~50ms
pause
처리량 ~95%
ZGC
<1ms
pause
처리량 ~98%
Serial GC 타임라인
STW
STW
앱 실행
STW (일시 정지)
Concurrent GC
Serial GC: 단일 스레드로 GC 수행. Mark-Compact 전체가 STW. 작은 힙/싱글 코어 환경에 적합.

면접 체크리스트

이 항목들을 자신 있게 설명할 수 있다면 GC 질문은 준비 완료입니다.

  • - GC의 판단 기준: 참조 카운트가 아니라 GC Root로부터의 도달 가능성
  • - Reference Counting: 즉시 해제, 순환 참조 취약
  • - Mark-and-Sweep: 순환 참조 처리, STW 발생
  • - 세대별 GC: Young Gen 분리로 효율 극대화, Full GC 빈도 줄이기가 핵심
  • - 최신 GC 트렌드: G1 → ZGC/Shenandoah → STW를 수 ms 이하로

참고 자료


의견을 들려주세요

서비스 개선에 큰 도움이 됩니다. 익명으로 자유롭게 남겨주세요.

0 / 1000