新項(xiàng)目為什么建議你使用 JDK17,一文告訴你升級(jí)的方法和不可拒絕的理由!
1、背景 TLDR;
垃圾回收器的暫停問(wèn)題對(duì)實(shí)時(shí)響應(yīng)要求較高的服務(wù)來(lái)說(shuō),一直是個(gè)痛點(diǎn), CMS和G1等主流垃圾回收器的數(shù)十毫秒乃至上百毫秒的暫停時(shí)間相當(dāng)致命。此外,調(diào)優(yōu)門檻也相對(duì)較高,需要對(duì)垃圾回收器的內(nèi)部機(jī)制有一定的了解,才能夠進(jìn)行有效的調(diào)優(yōu)。隨著ZGC的出現(xiàn), 使得這一痛點(diǎn)徹底解決, ZGC 最初在 JDK 11 中作為實(shí)驗(yàn)性功能引入,并在 JDK 15 中宣布為生產(chǎn)就緒, 由于 JDK17 才是比較正式提供給大眾實(shí)用的LTS支持版本,而且一部分公司已經(jīng)在使用,所以本文力推 JDK17。
ZGC 作為一款低延遲垃圾收集器,旨在滿足以下目標(biāo):
- 8MB 到 16TB 的堆大小支持
- 10ms 最大 GC 暫時(shí)
- 最糟糕的情況下吞吐量會(huì)降低 15%(實(shí)測(cè),如果參數(shù)配置的問(wèn)題可能更糟, 官方這個(gè)稍微吹牛了點(diǎn), 說(shuō)實(shí)話就是用 CPU 換 GC 時(shí)間,也沒(méi)有那么高大上)
1.1 升級(jí) JDK17 的不可拒絕的理由
低延遲的業(yè)務(wù)需求,毫秒級(jí)耗時(shí)的 GC
據(jù)美團(tuán)的開發(fā)說(shuō):
在 Zeus 服務(wù)不同集群中,ZGC 在低延遲(TP999 < 200ms)場(chǎng)景中收益較大:
- TP999:下降 12~142ms,下降幅度 18%~74%。
- TP99:下降 5~28ms,下降幅度 10%~47%。
可以忽略的升級(jí) JDK17 的理由:
- 新版的 Spring Boot 官方最低支持 JDK17,想使用新Spring版本,就得升級(jí);
- JIT 編譯器的增強(qiáng);
- JDK 17 中的新功能,例如 Sealed 類、Pattern Matching、Records 等;
- 升級(jí)到 JDK 17 可以獲得更好的安全性,包括修復(fù)的漏洞和強(qiáng)化的安全機(jī)制。
1.2 適用場(chǎng)景
- 網(wǎng)關(guān)服務(wù)
- Web API
暫不推薦場(chǎng)景:定時(shí)任務(wù)、批量任務(wù)、高 CPU 密集型應(yīng)用。
2、升級(jí)前后對(duì)比
話不多說(shuō),先看效果。
環(huán)境:
CPU:4c
Mem: 6GB
G1 參數(shù):
-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
ZGC 參數(shù):
--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
上述兩個(gè)參數(shù),均已經(jīng)在生產(chǎn)環(huán)境實(shí)驗(yàn)過(guò), 生產(chǎn)環(huán)境的機(jī)器是單機(jī)擁有 1500 業(yè)務(wù) tps 的機(jī)器。
2.1 GC 耗時(shí)對(duì)比
圖片
從上圖可見, GC 耗時(shí)是有著質(zhì)的區(qū)別的,這個(gè)區(qū)別是你用 CMS、Parallel GC、 G1 等嘔心瀝血也調(diào)校不出來(lái)的。
這么短的GC, 可以保證,應(yīng)用因?yàn)镴VM層面的卡頓都保持在 1ms 以內(nèi), 這也是為啥說(shuō)這點(diǎn)才是不能拒絕的理由。
2.2 CPU 使用對(duì)比
從 CPU 使用上看, JDK17 相同的代碼, 比 JDK8 要高出 10 ~ 20%
3、升級(jí)方法
3.1 JDK 選擇或安裝
使用 JDK17 前必須要安裝 JDK17, 對(duì)于不同的 Linux 發(fā)行版或者操作系統(tǒng)安裝方法各不相同, 下面給出了一些樣例, 僅供參考。
# ubuntu 安裝jdk17
sudo apt install openjdk-17-jdk
# docker 基礎(chǔ)鏡像
docker pull openjdk:17-slim
docker pull openjdk:17-jdk-oraclelinux7
FROM openjdk:17-slim
3.2 JVM 參數(shù)調(diào)整
有了 JDK17 后,已經(jīng)具備了讓你的 Java 程序運(yùn)行在 JDK17 上的基本條件了,下一步便是配置 JVM 參數(shù)如下(有需要的話,可以自行把換行整理下):
--add-opens=java.base/java.lang=ALL-UNNAMED \
-Xms1500m -Xmx1500m \
-XX:ReservedCodeCacheSize=256m \
-XX:InitialCodeCacheSize=256m \
-XX:+UnlockExperimentalVMOptions \
-XX:+UseZGC \
-XX:Cnotallow=1 -XX:ParallelGCThreads=2 \
-XX:ZCollectinotallow=30 -XX:ZAllocatinotallow=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
參數(shù)釋義
圖片