Why Upgrading to JDK 17 with ZGC Can Slash GC Pauses to Sub‑millisecond
This article explains how moving to JDK 17 and the low‑latency ZGC garbage collector can reduce pause times to under 10 ms, improve throughput, and meet demanding real‑time service requirements, while providing practical upgrade steps, JVM tuning parameters, and performance comparisons.
Background TLDR
Garbage‑collector pause times are a critical pain point for latency‑sensitive services; traditional collectors like CMS and G1 can pause for tens to hundreds of milliseconds, making them unsuitable for real‑time workloads. ZGC was introduced as an experimental feature in JDK 11, became production‑ready in JDK 15, and is officially supported in the LTS JDK 17, which many companies have already adopted.
ZGC, a low‑latency garbage collector, aims to meet the following goals:
Support heap sizes from 8 MB to 16 TB
Maximum GC pause ≤ 10 ms
Throughput penalty ≤ 15 % (real‑world may be higher depending on configuration)
Irrefutable Reasons to Upgrade to JDK 17
Low‑latency business requirements, millisecond‑level GC
According to developers at Meituan:
In Zeus service clusters, ZGC reduces TP999 by 12–142 ms (18 %–74 %) and TP99 by 5–28 ms (10 %–47 %).
Other, less critical, upgrade motivations include:
Spring Boot 3 officially requires JDK 17, so newer Spring versions need the upgrade.
Improvements in the JIT compiler.
New language features such as sealed classes, pattern matching, and records.
Enhanced security through patched vulnerabilities and hardened mechanisms.
Applicable Scenarios
Gateway services
Web APIs
Not recommended: scheduled tasks, batch jobs, CPU‑intensive workloads
Before‑and‑After Comparison
Environment:
<code>CPU: 4c
Mem: 6GB</code>G1 parameters:
<code>-Xmx3500m -Xms3500m -XX:+UseG1GC -XX:MaxGCPauseMillis=100
-XX:G1ReservePercent=10 -XX:ConcGCThreads=2 -XX:ParallelGCThreads=5
-XX:G1HeapRegionSize=16m -XX:MaxTenuringThreshold=14 -XX:SurvivorRatio=8</code>ZGC parameters:
<code>--add-opens=java.base/java.lang=ALL-UNNAMED -Xms3500m -Xmx3500m -XX:ReservedCodeCacheSize=256m -XX:InitialCodeCacheSize=256m -XX:+UnlockExperimentalVMOptions -XX:+UseZGC -XX:ConcGCThreads=1 -XX:ParallelGCThreads=3 -XX:ZCollectionInterval=60 -XX:ZAllocationSpikeTolerance=4 -XX:+UnlockDiagnosticVMOptions -XX:-ZProactive -Xlog:safepoint,classhisto*=trace,age*,gc*=info:file=/opt/gc-%t.log:time,tid,tags:filecount=5,filesize=50m</code>Both configurations have been tested in production on a single machine handling 1500 TPS.
GC time comparison
The GC pause shows a qualitative difference; such short pauses cannot be achieved with CMS, Parallel GC, or G1 even after extensive tuning. Sub‑millisecond GC keeps JVM‑induced latency below 1 ms, which is the key reason for upgrading.
CPU usage comparison
On the same workload, JDK 17 consumes 10 %–20 % more CPU than JDK 8.
Upgrade Method
1. Install JDK 17
Installation commands vary by Linux distribution. Example for Ubuntu:
<code># ubuntu install jdk17
sudo apt install openjdk-17-jdk
# Docker base images
docker pull openjdk:17-slim
docker pull openjdk:17-jdk-oraclelinux7
# Dockerfile
FROM openjdk:17-slim</code>2. Adjust JVM Parameters
After installing JDK 17, configure the JVM as follows (line breaks can be collapsed as needed):
<code>--add-opens=java.base/java.lang=ALL-UNNAMED \
-Xms1500m -Xmx1500m \
-XX:ReservedCodeCacheSize=256m \
-XX:InitialCodeCacheSize=256m \
-XX:+UnlockExperimentalVMOptions \
-XX:+UseZGC \
-XX:ConcGCThreads=1 -XX:ParallelGCThreads=2 \
-XX:ZCollectionInterval=30 -XX:ZAllocationSpikeTolerance=5 \
-XX:+UnlockDiagnosticVMOptions -XX:-ZProactive \
-Xlog:safepoint,classhisto*=trace,age*,gc*=info:file=/opt/gc-%t.log:time,tid,tags:filecount=5,filesize=50m \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=/opt/errorDump.hprof</code>Parameter Explanation
macrozheng
Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.