자바 가비지 컬렉션 (Garbage Collection) 정리
가비지 컬렉션(GC)은 JVM이 힙에서 더 이상 필요 없는 객체를 자동으로 회수하여 메모리 누수를 방지하고 안정적인 성능을 보장하는 핵심 기능입니다. 이 글에서는 GC의 동작 원리·알고리즘·JVM 옵션·모니터링을 한눈에 살펴봅니다.
가비지 컬렉션이란?
- 자동 메모리 관리 기술로, 개발자가
free()등을 호출하지 않아도 객체를 안전하게 해제합니다. - GC가 없는 환경에서는 메모리 누수(Leak)와 이중 해제(Double Free) 같은 오류가 빈번하지만, 자바는 Stop-The-World 단계에서 검증 후 회수하므로 안전성이 뛰어납니다.
키 포인트: GC는 안전성과 편의성을 제공하지만, 잘못 튜닝하면 일시 멈춤(Pause)으로 응답성이 저하될 수 있습니다.
힙 구조와 세대(Generation)
Young Generation
- Eden 영역에 새 객체가 생성됩니다.
- Minor GC가 발생하면 Survivor S0/S1로 객체를 복사하여 살아남은 횟수를 기록합니다.
Old Generation
- Survivor에서 여러 차례 살아남은 객체가 Promotion되어 장기 보관됩니다.
- 객체 크기가 크거나, 처음부터 오래 살아남을 것으로 예상되면 직접 Old로 할당되는 경우도 있습니다.
핵심 알고리즘 비교
| 알고리즘 | 동작 방식 | 장점 | 단점 |
|---|---|---|---|
| Mark-Sweep | 도달 가능 객체마크→ 미사용 영역스윕 | 구현 단순 | 메모리 단편화 |
| Copying | 사용 객체만 새 영역으로 복사 | 단편화 해소, 빠른 할당 | 메모리 사용률 ↓ |
| Generational GC | 세대별 특성에 맞춰 Minor/Major GC | 평균 지연 ↓ | 튜닝 필요 |
| G1 GC | 힙을 작은Region으로 나누고 병렬·동시 GC | 저지연, 대용량 힙 | 초기 튜닝 복잡 |
GC 트리거와 Stop-The-World
- Minor GC: Eden이 가득 차면 발생하며, 짧은 Pause가 발생합니다.
- Major (Old) GC: Old 영역이 임계치를 초과하면 발생하며, Pause가 길어집니다.
- Full GC: 힙 전체를 대상으로 하며, 최악의 응답 지연이 발생하므로 로그를 주의 깊게 모니터링해야 합니다.
JVM GC 옵션 빠른 레시피
# 8 GB 힙, G1 GC 사용, GC 상세 로그 출력
java -Xms4g -Xmx8g \\
-XX:+UseG1GC \\
-XX:+PrintGCDetails \\
-XX:+PrintGCDateStamps \\
-Xloggc:logs/gc.log \\
-jar app.jar
Xms/-Xmx: 힙 초기·최대 크기 설정XX:+UseG1GC: 저지연용 G1 사용XX:MaxGCPauseMillis=200: 목표 Pause 시간 힌트XX:+PrintGCDetails: GC 원인·소요 시간 로그
GC 모니터링 & 튜닝 프로세스
- 로그 확보 – 위 옵션으로
gc.log수집 - 시각화 도구 – GCViewer, GCEasy로 Pause 패턴 분석
- 병목 파악 – 빈번한 Full GC, Promotion Failure 여부 확인
- 옵션 조정 – 힙 사이즈·Region 크기·GC 유형 변경 후 재측정
Tip: JDK 11 이상에서는 JFR(Java Flight Recorder)로 CPU·메모리·GC 이벤트를 통합 분석할 수 있습니다.
질문 정리
- Minor GC와 Major GC는 왜 속도 차이가 큰가요?Young 영역(작음)은 Copy GC 중심이라 빨리 끝나지만, Old 영역(큼)은 Mark-Sweep-Compact 과정을 거쳐 시간이 더 소요됩니다.
- Stop-The-World를 완전히 없앨 수 있나요?완전 제거는 불가능하지만, ZGC·Shenandoah(저지연 GC)로 Pause 시간을 수 ms로 줄일 수 있습니다.
System.gc()호출은 권장되나요?대부분의 경우 권장되지 않습니다. 명시적 호출이 예상치 못한 Full GC를 유발하여 성능을 저하시킬 수 있습니다.- 메모리 누수를 GC가 자동 해결해 주나요?객체를 여전히 참조하고 있으면 GC가 회수하지 못합니다. 참조 해제를 통해 누수를 직접 방지해야 합니다.
- GC 로그에서
Promotion Failure가 보이면 어떻게 해야 하나요?Old 영역이 부족해 Young 객체를 승격하지 못한 상황입니다. Old 크기 확대 또는 객체 생성 패턴 개선이 필요합니다.
댓글남기기