寫在前邊
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端程序是很適合的,設置過大會使堆變大,直至接近最大堆設置的值。
官方建議策略
- 盡量不設置最大堆,選擇合適的目標吞吐量
- 如果可以達到吞吐量目標,但是暫停時間太長,請選擇一個暫停時間目標進行折衷(以降低吞吐量為代價)
- 如果未達到吞吐量目標,請設置盡可能大的堆(小於物理可用內存)
參考
- 《深入理解Java虛擬機高級特性與最佳實踐》第2版
- https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gc-ergonomics.html