본문 바로가기
language/java

G1 GC (Garbage First GC)

by 죄니안죄니 2026. 6. 29.
반응형

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
 

를 비교한다.

핵심 차이만 먼저 보면

항목G1 GCZGC
목표 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의 핵심 기술을 실무 관점에서 깊이 있게 살펴본다.

반응형

댓글