談JVM引數GC執行緒數ParallelGCThreads合理性設定
作者:京東零售 劉樂
1. ParallelGCThreads引數含義
在講這個引數之前,先談談JVM垃圾回收(GC)演算法的兩個優化標的:吞吐量和停頓時長。JVM會使用特定的GC收集執行緒,當GC開始的時候,GC執行緒會和業務執行緒搶佔CPU時間,吞吐量定義為CPU用於業務執行緒的時間與CPU總消耗時間的比值。為了承接更大的流量,吞吐量越大越好。
為了安全的垃圾回收,在GC或者GC某個階段,所有業務執行緒都會被暫停,也就是STW(Stop The World),STW持續時間就是停頓時長,停頓時長影響響應速度,因此越小越好。
這兩個優化目標是有衝突的,在一定範圍內,參與GC的執行緒數越多,停頓時長越小,但吞吐量也越小。生產實踐中,需要根據業務特點設定一個合理的GC執行緒數,取得吞吐量和停頓時長的平衡。
目前廣泛使用的GC演算法,包括PS MarkSweep/PS Scavenge, ConcurrentMarkSweep/ParNew, G1等,都可以通過ParallelGCThreads引數來指定JVM在並行GC時參與垃圾收集的執行緒數。該值設定過小,GC暫停時間變長影響RT,設定過大則影響吞吐量,從而導致CPU過高。
2. ParallelGCThreads引數設定
GC併發執行緒數可以通過JVM啟動引數: -XX:ParallelGCThreads=<N>來指定。在未明確指定的情況下,JVM會根據邏輯核數ncpus,採用以下公式來計算預設值:
◦當ncpus小於8時,ParallelGCThreads = ncpus
◦否則 ParallelGCThreads = 8 + (ncpus - 8 ) ( 5/8 )
一般來說,在無特殊要求下,ParallelGCThreads引數使用預設值就可以了。但是在JRE版本1.8.0_131之前,JVM無法感知Docker的CPU限制,會使用宿主機的邏輯核數計算預設值。 比如部署在128核物理機上的容器,JVM中預設ParallelGCThreads為83,遠超過了容器的核數。過多的GC執行緒數搶佔了業務執行緒的CPU時間,加上執行緒切換的開銷,較大的降低了吞吐量。因此JRE 1.8.0_131之前的版本,未明確指定ParallelGCThreads會有較大的風險。
3. ParallelGCThreads引數實驗
建立 8C12G 容器,宿主機是128C。模擬線上真實流量,採用相同QPS,觀察及對比JVM YoungGC,JVM CPU,容器CPU等監控資料。場景如下:
◦場景1: JVM ParallelGCThreads 預設值,QPS = 420,持續5分鐘,CPU恆定在70%
◦場景2: JVM ParallelGCThreads=8,QPS = 420,持續5分鐘,CPU恆定在65%
◦場景3: JVM ParallelGCThreads 預設值,QPS瞬時發壓到420,前1min CPU持續100%
◦場景4: JVM ParallelGCThreads=8,QPS瞬時發壓到420,前2s CPU持續100%,後面回落
從監控資料來看,各場景下CPU差距較明顯,特別是場景3和場景4的對比。場景3由於GC執行緒過多,CPU持續100%時長達1分鐘。可以得出以下兩個結論:
1.修改 ParallelGCThreads = 8後,同等QPS情況下,CPU會降低5%左右
2.修改 ParallelGCThreads = 8後,瞬間發壓且CPU打滿情況下,CPU恢復較快
圖1: 容器CPU對比圖:場景3(上)和場景4(下)
圖2: JVM Young GC對比圖:場景3(上)和場景4(下)
4. ParallelGCThreads修改建議
ParallelGCThreads配置存在風險的應用,修改方式為以下兩種方案(任選一種):
◦升級JRE版本到1.8.0_131以上,推薦1.8.0_192
◦在JVM啟動引數明確指定 -XX:ParallelGCThreads=<N>,N為下表的推薦值:
容器核數 | 2 | 4 | 8 | 16 | 32 | 64 |
---|---|---|---|---|---|---|
推薦值 | 2 | 4 | 8 | 13 | 23 | 43 |
建議上下界 | 1~2 | 2~4 | 4~8 | 8~16 | 16~32 | 32~64 |
- 應用健康度隱患刨析解決系列之資料庫時區設定
- 對於Vue3和Ts的心得和思考
- 一文詳解擴散模型:DDPM
- zookeeper的Leader選舉原始碼解析
- 一文帶你搞懂如何優化慢SQL
- 京東金融Android瘦身探索與實踐
- 微前端框架single-spa子應用載入解析
- cookie時效無限延長方案
- 聊聊前端效能指標那些事兒
- Spring竟然可以建立“重複”名稱的bean?—一次專案中存在多個bean名稱重複問題的排查
- 京東金融Android瘦身探索與實踐
- Spring原始碼核心剖析
- 深入淺出RPC服務 | 不同層的網路協議
- 安全測試之探索windows遊戲掃雷
- 關於資料庫分庫分表的一點想法
- 對於Vue3和Ts的心得和思考
- Bitmap、RoaringBitmap原理分析
- 京東小程式CI工具實踐
- 測試用例設計指南
- 當你對 redis 說你中意的女孩是 Mia