Parallel收集器概述
Parallel收集器分别独立地回收新生代和老年代,并且回收过程是多线程执行等(即有多个GC线程)。新生代回收过程称为Minor GC,老年代回收过程称为Major GC。在默认情况下,Parallel收集器的Minor GC和Major GC同时进行。
如何启用Parallel收集器
目前,大部分后台服务器都是默认使用Parallel收集器,也就是说jvm如果是server模式,那么默认所使用的垃圾收集器就是Parallel收集器。手动开启Parallel收集器的选项:
-XX:+UseParallelGC
Parallel收集器的线程数
假如没有手动设置Parallel收集器的GC线程数,那么GC线程数与CPU个数N存在关系
- 当N=1的时候,Parallel收集器要比Serial收集器(只用1个线程)性能差。
- 当N=2的时候,Parallel收集器要比Serial收集器(只用1个线程)性能略好(在堆不是特别小的情况下)。
- 当N>2的时候,Parallel收集器要比Serial收集器(只用1个线程)性能好得多。
也可以强制指定Parallel收集器的GC线程数:
-XX:ParallelGCThreads=<N>
如果强制指定了GC线程数,堆大小也要设置成一个合理值才能得到较好的性能。另外,GC线程越多,则越容易在老年代中产生空间碎片。这是因为GC线程在进行Minor GC的时候,需要在老年代中预留一部分空间存放新生代中存活的对象,导致对老年代进行了一些空间划分,很容易产生空间碎片。
Parallel收集器的调优方法
Parallel收集器支持指定某些优化目标,例如最大停顿时间、最大吞吐量。当指定了这些优化目标之后,堆的大小会被动态调整从而来尽可能达到你的目标。
- 优化目标1: 指定最大停顿时间N毫秒(不传该选项时,停顿时间不受限制):
-XX:MaxGCPauseMillis=<N>
指定了最大停顿时间之后,Parallel收集器会自动调整堆大小,以匹配设定的目标。如果停顿时间设定较短,则吞吐量可能相应降低。
- 优化目标2: 指定目标吞吐量
-XX:GCTimeRatio=<N>
对于垃圾收集器而言,吞吐量只能用消耗在应用程序上的时间和消耗在GC上的时间来度量,因此用一个比率N来描述吞吐量。简单的说,比率N用于分配一定比例的时间给GC,这个比例是1/(1 +N)。N越大分配给应用的时间越多,N的默认值是99。
- 优化目标3: 指定最大堆大小
-Xmx<N>
指定该选项以后,Parallel收集器会保证堆的大小尽量小于N。
针对以上3个优化目标,Parallel收集器优先保证最大停顿时间尽量小,然后再保证吞吐量尽可能大,最后保证最大堆大小尽可能小。当停顿时间达不到目标时,新生代和老年代将被缩小;当吞吐量达不到目标时,新生代和老年代将被扩张。
堆大小的指定
使用Parallel回收器时,可以不指定初始堆大小(-Xms<N>)和最大堆大小(-Xmx<N>),会根据机器的物理内存计算一个值。当然,你指定了就是用你设定的值。这里有个地方容易误会:最大堆大小并不能保证一定要分配那么多空间给JVM,JVM如果发现空间够用的话,是不会占用那么多内存的,只有当对象足够多的时候,JVM才会使用这个参数。
- 如果你知道自己的堆该设为多大,那么可以把-Xms和-Xmx设为一样的值;
- 如果你不知道堆应该设为多大,那么不要设置这两个值,让虚拟机自动计算,等运行一段时间达到平衡状态后,看当前最大堆大小是多少。
可以参考文档:https://docs.qq.com/doc/DQVZmeHpBdWJBeXpi