ZGC
1 ZGC
- The Z Garbage Collector
- JDK 11에서 처음 선보였고 JDK 15부터 Production Ready 상태
1.1 ZGC의 목표
JEP333에서 설정한 목표
- GC pause time이 10ms를 초과하지 않기
- 작은 사이즈의 힙(a few hundreds of megabytes)부터 큰 사이즈의 힙(many terabytes)까지 지원하기
- G1 gc와 비교하여 throughput 저하를 최대 15%까지만 허용하기
- low-latency을 중시하기 때문에 그만큼 throughput이 희생된다.
추가적인 목표
- 쉬운 튜닝
- The Java ZGC is easy to use and require minimal configuration.
JEP: JDK Enhancement Proposals
1.2 ZGC란?
ZGC is a scalable low-latency garbage collector
low latency
- 최대 1ms의 pause times
- JEP 333에서는 10ms이하지만 JEP 333의 작성자 Per Liden의 영상에서는 1ms이하로 설정
- ZGC - The Future of Low-Latency Garbage Collection Is Here 여기 참고
- JDK 16이후부터 1ms 이하로 목표 설정
- Erik Österlund — Concurrent thread-stack processing in the Z Garbage Collector 참고
scalable
- Pause times do not increase with root-set size
- ZGC pause O(1)
- 최소 힙 사이즈 8MB
- 최대 힙 사이즈 16TB
- JEP 377: ZGC: A Scalable Low-Latency Garbage Collector (Production)를 통해서 4TB에서 16TB로 상승했다.
root set
- root set으로부터 시작한 참조 사슬에 속한 객체들은 reachable 객체이고, 이 참조 사슬과 무관한 객체들이 unreachable 객체로 GC 대상이다
Ease of use
- The Java ZGC is easy to use and require minimal configuration.
1.3 ZGC의 특징 요약
Concurrent
- 자바 쓰레드가 실행되는 동시에 GC 쓰레드가 백그라운드에서 실행된다.
- 동기화를 위한 짧은 STW를 제외하고 거의 모든 GC 작업(marking, heap defragmentation)이 자바 쓰레드와 동시에 진행된다.
Region-based
- 힙은 3가지 종류의 특정 사이즈의 regions들로 구성된다.
Compacting
- 메모리 단편화를 막기위해 주기적으로 살아있는 객체들을 한 region에서 다른 region으로 옮긴다.
Single Generation(Non-generational)
- 전체 힙을 대상으로 GC cycle이 진행된다.
- 기존의 GC 처럼 young generation과 old generation의 구분이 없다.
- Generational ZGC는 현재 진행중에 있다.
- JEP 439: Generational ZGC
Using colored pointers
Using load barriers
NUMA-aware
1.4 GC 선정 기준
1.4.1 Maximum Pause-Time
- 레퍼런스
- Pause-Time이란 garbage collector가 애플리케이션을 멈추고 가비지를 수집하는 시간이다.
- Maximum Pause-Time은 Pause-Time의 최대치를 제한하는 목적이다.
- Maximum Pause-Time은
-XX:MaxGCPauseMillis=<nnn>옵션으로 설정할 수 있다.- 이 옵션을 설정한다고 해서 pause-time 목표가 무조건 달성되는 것은 아니다.
- GC는 해당 목표를 달성하기 위해 힙의 사이즈와 관련된 파라미터를 조절한다.
- 기본 Maximum Pause-Time은 gc의 종류마다 다르다.
- 이러한 조절이 gc가 더 많이 발생하게 할 수도 있고 throughput을 저하시킬수도 있다.
1.4.2 Throughput Goal
- 가비지를 수집하는 시간과 애플리케이션 동작하는 시간의 비율이다.
-XX:GCTimeRatio=nnn옵션으로 비율을 지정할 수 있다.- 가비지 수집 시간과 애플리케이션이 동작하는 비율이 1 / (1 + nnn)이라는 의미다.
- 예를 들어
-XX:GCTimeRatio=19로 옵션을 지정하면 비율은 1/20으로 애플리케이션 동작 시간의 5%만 가비지 수집 시간으로 사용한다.
1.4.3 Footprint
- throughput과 maximum pause-time 목표가 모두 달성되면 gc는 둘 중 하나의 목표가 충족되지 않을 때까지 힙의 사이즈를 줄인다.
- 주로 throughput이 총족되지 못한다.
- 최소 힙 사이즈를 설정하는 옵션:
-Xms=<nnn> - 최대 힙 사이즈를 설정하는 옵션:
-Xmx=<mmm>
1.4.4 비교
- 여러 GC들의 목표를 비교해보자
- 모든 기준을 만족시키는 하나의 GC는 없기 때문에 상황에 맞게 GC를 선택해야한다.



출처: Java’s Highly Scalable Low-Latency Garbage Collector : ZGC
2 성능
2.1 G1과 비교
Thoughput과 Lataency 비교

- Thoughput은 G1이 더 좋다.
- Lataency는 ZGC가 더 좋다.
GC Pause time 비교

- ZGC는 1ms 이하라 보이지도 않는다.

- 마이크로 세컨으로 단위 변경 후
2.2 JDK 버전과 성능 향상



2.3 Non-generation과 Generational ZGC 성능 비교
- Generational ZGC는 아직 개발 중이지만 먼저 Non-generation ZGC와 성능 비교를 해보자.
메모리 사용량

성능
- Generational ZGC가 메모리를 덜 쓰지만 성능이 더 잘나옴

CPU 사용량

