1、Parallel Scavenge 收集器
Parallel Scavenge 收集器是一個新生代收集器,采用復制算法,並且是多線程收集器;Parallel Scavenge 收集器的關注點與其他收集器不同,CMS等收集器的關注點是盡可能縮短垃圾收集時用戶線程的停頓時間,而Parallel Scavenge 收集器的目標則是達到一個可控制的吞吐量(Throughput)。這里所謂的吞吐量是指CPU用於運行用戶代碼的時間與CPU總消耗時間的比值,既吞吐量 = 運行用戶代碼時間 / (運行用戶代碼時間 + 垃圾收集時間)
,虛擬機總共運行了100分鍾,其中垃圾收集花掉了1分鍾,那么吞吐量就是99%。
停頓時間越短就越適合需要與用戶交互的程序,良好的響應速度能提升用戶體驗,而高吞吐量則可以高效的利用CPU時間,盡快完成程序的運算任務,主要適合在后台運算而不需要太多交互的任務。
Parallel Scavenge 收集器提供了兩個參數用於精確控制吞吐量,分別是控制最大垃圾收集停頓時間的-XX:MaxGCPauseMillis
參數以及直接設置吞吐量大小的-XX:GCTimeRatio
參數。
MaxGCPauseMillis:參數允許的值是一個大於0的毫秒數,收集器將盡可能地保證內存回收花費的時間不超過設定值。不過不要認為如果把這個參數的值設置得稍小一點就能使得系統的垃圾收集速度變得更快,GC停頓時間縮短是以犧牲吞吐量和新生代空間換取來的:系統把新生代調小一些,收集300MB新生代肯定比收集500MB快吧,這也直接導致垃圾收集發生得更頻繁一些,原來10秒收集一次、每次停頓100毫秒,現在變成5秒收集一次,每次停頓70毫秒。停頓時間的確在下降,但吞吐量也降下來了。
GCTimeRatio:參數的值是一個大於0且小於100的整數,也就是垃圾收集時間占總時間的比率,相當於是吞吐量的倒數。如果把此參數設置為19,那允許的最大GC時間就占總時間的5%(既1 /(1 + 19)
),默認值為99,就是允許最大1%(既 1 /(1 + 99)
)的垃圾收集時間。
由於與吞吐量關系密切,Parallel Scavenge 收集器也經常稱為“吞吐量優先”收集器。Parallel Scavenge 收集器還有一個參數-XX:+UseAdaptiveSizePolicy
,這是一個開關參數,當這個參數打開之后,就不需要手工指定新生代的大小(-Xmn
)、Eden與Survivor區的比例(-XX:SurivivorRatio
)、晉升老年代對象年齡(-XX:PretenureSizeThreshold
)等細節參數了,虛擬機會根據當前系統的運行情況收集性能監控信息,動態調整這些參數以提供最合適的停頓時間或者最大的吞吐量,這種調節方式稱為GC自適應的調節策略(GC Ergonomics)。假設對收集器運作原理不太了解,只需要把基本的內存數據設置好(如 -Xmx
設置最大堆),然后使用MaxGCPauseMillis
參數(更關注最大停頓時間)或者GCTimeRatio
(更關注吞吐量)參數給虛擬機設立一個優化目標,那具體細節參數的調節工作就由虛擬機完成了。自適應調節策略也是Parallel Scavenge收集器與ParNew收集器的一個重要區別。
2、Parallel Old 收集器
Parallel Old 收集器是Parallel Scavenge 收集器的老年代版本,使用多線程和“標記-整理”算法。在注重吞吐量以及CPU資源敏感的場合,可以優先考慮Parallel Scavenge 加 Parallel Old 收集器。
3、Parallel Scavenge + Parallel Old 收集器
參考資料
1.《深入理解Java虛擬機:JVM高級特性與最佳實踐》(第2版);
2.Java HotSpot Virtual Machine Garbage Collection Tuning Guide Release 8。