写在前边
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