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