G1 GC (Garbage First GC)
Java를 사용하다 보면 JVM 옵션에서 가장 많이 보게 되는 GC가 있다.
-XX:+UseG1GC
또는 JDK 9 이상에서는
별도의 설정 없이도 기본 GC로 동작한다.
그만큼 현재 실무에서 가장 많이 사용되는 GC다.
하지만 많은 개발자가
"G1이 최신 GC니까 무조건 가장 빠르다."
라고 생각한다.
이건 틀린 말이다.
G1 GC의 목표는
처리량(Throughput)이 아니라 예측 가능한 Pause Time을 만드는 것이다.
이번 글에서는
- 기존 GC가 가진 문제
- G1이 등장한 이유
- Region 구조
- Young GC
- Mixed GC
- Concurrent Marking
- Pause Time
- 실무에서 G1을 언제 사용하는지
까지 알아본다.
왜 G1 GC가 등장했을까?
예전에는
- Serial GC
- Parallel GC
- CMS GC
가 많이 사용됐다.
하지만 Heap이 커질수록 문제가 생겼다.
예를 들어
Heap : 32GB
Old Generation 전체를 검사해야 한다.
↓
Full GC 발생
↓
Stop-The-World
↓
10초
20초
30초
멈춤
대용량 서비스에서는
이 Pause Time이 치명적이었다.
그래서 등장한 것이
G1
(Garbage First)
이다.
이름의 의미
Garbage First
뜻 그대로
쓰레기가 가장 많은 곳부터
먼저 청소한다.
이다.
기존 GC는
Young
↓
Old
↓
전체
같이 영역 단위로 관리했다.
G1은
Heap 자체를
수백~수천 개의 작은 블록으로 나눈다.
Region 구조
기존 구조
Heap
├── Young
└── Old
G1
Heap
□□□□□□□□□□□□□□□□□□□□□□
□□□□□□□□□□□□□□□
□□□□□□□□□□□□□□□□□□□□□□
모든 칸이
Region
이다.
예를 들어
Heap
[ ][ ][ ][ ][ ][ ][ ][ ]
각각이
독립적인 Region이다.
Region 하나의 크기는
1MB
~
32MB
사이에서 JVM이 자동 결정한다.
Heap 크기에 따라 달라진다.
Region은 역할이 바뀐다
기존 GC
Young
Old
가 고정이었다.
G1은
Region이
동적으로 역할을 가진다.
예를 들어
Region 1 → Eden
Region 2 → Eden
Region 3 → Survivor
Region 4 → Old
Region 5 → Old
필요하면
나중에
Region 3
↓
Old
로 바뀔 수도 있다.
즉
Heap 전체가 유연하게 동작한다.
Young GC
객체 생성
↓
Eden Region 저장
↓
가득 참
↓
Young GC
↓
살아있는 객체
↓
Survivor 이동
↓
Promotion
↓
Old Region
기본 개념은 기존 GC와 거의 동일하다.
G1의 핵심
중요한 차이는
Old Generation 관리다.
기존 GC는
Old 전체를 검사했다.
G1은
Region별
Garbage 비율
을 계산한다.
예를 들어
Region A
90% 쓰레기
Region B
10% 쓰레기
그러면
먼저
Region A
를 청소한다.
이것이
Garbage First다.
Concurrent Marking
Old Region을 청소하려면
살아있는 객체를 먼저 찾아야 한다.
이를
Mark
라고 한다.
기존 Full GC
Stop-The-World
↓
Mark
↓
Sweep
↓
Compact
G1은
Mark 대부분을
애플리케이션과 동시에 수행한다.
Application
↓
Concurrent Marking
↓
사용자는 계속 요청 처리
즉
전체를 멈추지 않는다.
Mixed GC
G1의 대표적인 특징
기존 GC
Young GC
또는
Full GC
둘 중 하나
G1
Young GC
뿐 아니라
Mixed GC
가 있다.
Mixed GC란
Young Region
+
Garbage가 많은 Old Region
을
같이 청소한다.
즉
Full GC까지 가지 않고
Old도 조금씩 정리한다.
예를 들어
Young
Old A (90%)
Old B (85%)
Old C (5%)
이면
청소 대상은
Young
Old A
Old B
Old C는
다음에 한다.
Pause Time 목표
G1은
Pause Time 목표를 설정할 수 있다.
-XX:MaxGCPauseMillis=200
옵션 설명
- -XX:MaxGCPauseMillis=200
- GC Pause Time 목표를 약 200ms로 설정한다.
- 보장값이 아니라 목표(Target) 다.
많은 사람이
200ms 넘지 않는다.
라고 오해한다.
아니다.
JVM은
가능하면
200ms 근처로 맞추려고
Region 개수를 조절한다.
즉
절대값
X
목표값
O
이다.
Full GC가 없어지는가?
아니다.
G1도
Full GC는 존재한다.
예를 들어
- Heap 부족
- Promotion 실패
- 심각한 메모리 압박
이런 상황에서는
여전히
Full GC
가 발생한다.
다만
발생 빈도를 줄이는 것이 목적이다.
G1의 장점
Pause Time 예측 가능
대용량 Heap에서도
긴 STW를 줄일 수 있다.
Heap이 커질수록 유리
예를 들어
16GB
32GB
64GB
Heap에서는
기존 GC보다 훨씬 유리하다.
Mixed GC
Old Generation을
조금씩 정리한다.
자동 튜닝
기본 설정만으로도
상당히 좋은 성능을 제공한다.
단점
작은 Heap에서는 이득이 적다
예를 들어
Heap
512MB
라면
Parallel GC가 더 빠른 경우도 있다.
CPU 사용량 증가
Concurrent Marking 때문에
백그라운드 스레드가 동작한다.
CPU를 더 사용한다.
내부 구조가 복잡하다
튜닝 포인트가 많다.
실제로는
기본 설정을 사용하는 경우가 많다.
실무에서는 언제 사용할까?
Spring Boot
↓
Java 17
↓
Heap 4GB 이상
↓
G1
거의 기본 선택이다.
대부분의 웹 서비스는
별다른 이유가 없다면
기본 G1으로 충분하다.
G1 튜닝은 언제 할까?
실무에서는
옵션부터 수정하지 않는다.
순서는
GC 로그 분석
↓
Heap Dump 확인
↓
객체 생성 패턴 분석
↓
메모리 누수 확인
↓
G1 옵션 조정
이다.
옵션 변경은
마지막 단계다.
G1에서 자주 보는 옵션
-XX:+UseG1GC
옵션 설명
- -XX:+UseG1GC
- G1 GC를 사용한다.
-XX:MaxGCPauseMillis=200
옵션 설명
- -XX:MaxGCPauseMillis=200
- 목표 Pause Time을 200ms로 설정한다.
-Xms4g
-Xmx4g
옵션 설명
- -Xms4g
- JVM 시작 Heap을 4GB로 설정한다.
- -Xmx4g
- Heap 최대 크기를 4GB로 설정한다.
실무에서는 -Xms와 -Xmx를 동일하게 설정해 Heap 확장/축소 비용을 줄이는 경우가 많다.
ZGC와의 차이
많은 사람이
G1
vs
ZGC
를 비교한다.
핵심 차이만 먼저 보면
| 목표 | Pause Time 단축 | 초저지연(Low Latency) |
| Pause | 수십~수백 ms | 보통 1ms 이하 |
| Heap | 중대형 | 매우 큰 Heap |
| CPU 사용 | 보통 | 더 높음 |
| 실무 사용 | 가장 많음 | 점점 증가 |
ZGC는 다음 글에서 자세히 다룬다.
지금까지의 연결
객체 생성
↓
Young Region
↓
Minor GC
↓
Promotion
↓
Old Region
↓
Concurrent Marking
↓
Mixed GC
↓
필요 시 Full GC
즉
G1은
Old Generation을
한 번에 청소하지 않고
조금씩 지속적으로 관리하는 GC다.
정리
G1 GC는
"가장 빠른 GC"가 아니라 "Pause Time을 예측 가능하게 만드는 GC" 다.
핵심 아이디어는
Heap
↓
Region 분할
↓
Garbage가 많은 Region부터
↓
조금씩 청소
이다.
그래서
대용량 Heap에서도
긴 Full GC를 최대한 줄일 수 있다.
현재 Spring Boot + Java 17 이상 환경에서는 특별한 이유가 없다면 G1 GC가 가장 무난한 기본 선택이다.
다음 글에서는 ZGC (Z Garbage Collector) 를 다룬다.
왜 "Pause Time 1ms 이하"라는 말이 나오는지, Colored Pointer와 Concurrent Relocation 같은 ZGC의 핵심 기술을 실무 관점에서 깊이 있게 살펴본다.
'language > java' 카테고리의 다른 글
| ZGC (Z Garbage Collector) - 초저지연 GC의 원리 (0) | 2026.06.29 |
|---|---|
| GC 튜닝 기초 (왜 대부분의 성능 문제는 GC보다 객체 생성 패턴에서 시작되는가) (0) | 2026.06.29 |
| Escape Analysis 재방문 (Scalar Replacement, Lock Elision) (0) | 2026.06.29 |
| 객체 생성 비용 줄이기 (Object Creation Cost) (0) | 2026.06.29 |
| Spring MVC 예외 처리 내부 구조 (0) | 2026.06.24 |
댓글