小知識點 之 JVM -XX:MaxGCPauseMillis 與 -XX:GCTimeRatio
阿新 • • 發佈:2020-11-29
## 寫在前邊
JVM調優更多是針對不同應用型別及目標進行的調整,往往有很大的實驗成份,通過實驗來針對當前應用設定相對合適的引數,提高應用程式的效能與穩定性
最近在複習JVM,Parallel Scavenage GC收集器是一個新生代、複製演算法、並行多執行緒收集器,主要目標是控制吞吐量與GC的停頓時間。
Parallel Scavenage GC提供兩個引數 `-XX:MaxGCPauseMillis` 與 `-XX:GCTimeRatio` 自動調整堆大小與其他與GC相關的引數,達到GC調優的目的
## -XX:MaxGCPauseMillis=nnn
表示每次GC最大的停頓毫秒數,VM將調整Java堆大小和其他與GC相關的引數,以使GC引起的暫停時間短於nnn毫秒,儘可能地保證記憶體回收花費時間不超過設定值。
請注意,這可能會導致VM降低整體吞吐量(吞吐量=執行使用者程式碼時間/VM總執行時間),並且在某些情況下,VM將無法達到所需的暫停時間目標。
預設情況下,VM沒有暫停時間目標值。GC的暫停時間主要取決於堆中實時資料的數量與實時資料量。
該引數應謹慎使用。太小的值將導致系統花費過多的時間進行垃圾回收。原因是為滿足最大暫停時間,VM將設定更小的堆,以儲存相對少量的物件,來提升回收速率,會導致更高頻率的GC。
## -XX:GCTimeRatio=nnn
表示希望在GC花費不超過應用程式執行時間的1/(1+nnn),nnn為大於0小於100的整數。
換句話說,此引數的值表示執行使用者程式碼時間是GC執行時間的nnn倍。
舉個官方的例子,引數設定為19,那麼GC最大花費時間的比率=1/(1+19)=5%,程式每執行100分鐘,允許GC停頓共5分鐘,其吞吐量=1-GC最大花費時間比率=95%
預設情況下,VM設定此值為99,執行使用者程式碼時間是GC停頓時間的99倍,即GC最大花費時間比率為1%
選擇此引數應對server端程式是很適合的,設定過大會使堆變大,直至接近最大堆設定的值。
## 官方建議策略
1. 儘量不設定最大堆,選擇合適的目標吞吐量
2. 如果可以達到吞吐量目標,但是暫停時間太長,請選擇一個暫停時間目標進行折衷(以降低吞吐量為代價)
3. 如果未達到吞吐量目標,請設定儘可能大的堆(小於物理可用記憶體)
## 參考
- 《深入理解Java虛擬機器高階特性與最佳實踐》第2版
- https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gc-ergonom