描述: java虚拟机规范并未对垃圾收集器的具体实现做规范,所以不同厂商、不同版本虚拟机实现不一致;但一般都会提供参数能够进行垃圾回收器之间的组合。
注:
基于JDK1.7Update14之后的HotSpot虚拟机
新生代收集器:Serial、ParNew、Parallel Scavenge;
老年代收集器:Serial Old、Parallel Old、CMS;
G1 收集器
上图展示了7种收集器,白色区域为新生代收集器,灰色区域为老年代收集器。如果两个收集器之间存在连线,就说明它们可以搭配使用。
任何虚拟机都需要集合具体环境、场景等进行合理选择,只有最合适的。
Serial收集器是一个新生代收集器,单线程收集器,使用复制算法,单线程
,指不仅仅只会使用一个CPU或者一条收集线程去完成垃圾收集,更重要的是它在进行垃圾收集时,必须暂停其他所有线程的工作
如图展示: 在安全点需要暂停所有用户线程,(Stop The World)
Serial收集器是虚拟机运行在Client模式下的默认新生代收集器。其优点:简单而高效(与其他收集器的单线程比),对于限定单个CPU的环境来说,Serial收集器减少了线程交互的开销。 所以运行在Client模式下的虚拟机来说是一个不错的选择。
总结:
描述项 | 具体细节 |
---|---|
特点描述 | 针对新生代,复制算法、单线程收集,进行垃圾收集时,必须暂停所有工作线程,直到完成(Stop the world) |
应用场景 | 虚拟机运行在Client模式下的默认新生代收集器 |
优点 | 简单高效(与其他收集器的单线程相比) |
缺点 | JVM在后台自动发起和自动完成的,把用户正常的工作线程全部停掉,即GC停顿 会带给用户不良的体验 |
ParNew收集器其实就是serial收集器的多线程版本,除了使用多条线程进行垃圾收集之外,其余行为与Serial收集器一样;实现上,也共用了相当多的代码。
虽然与Serial收集器只是在收集垃圾时采用多线程外,没有其他太多的变化。但是它确实许多运行在Service模式下虚拟机中首选的新生代收集器,其中一个与性能无关的原因就是除了
Serial
收集器外,目前只有ParNew
收集器能与CMS
收集器配合工作。
ParNew 收集器也是使用 -XX:+UseConcMarkSeepGC
选项后的默认新生代收集器,也可以使用-XX:UseParNewGC
选项来强制指定;
默认开启的垃圾收集器线程数就是CPU数量,可通过-XX:parallelGCThreads
参数来限制收集器线程数
Serial收集器 VS ParNew收集器:
单CPU,ParNew 不会比Serial收集效果更好,但是随着CPU的数量增加。ParNew则在GC时对系统资源有效利用更好
参数小节:
"-XX:+UseConcMarkSweepGC":指定使用CMS后,会默认使用ParNew作为新生代收集器;
"-XX:+UseParNewGC":强制指定使用ParNew;
"-XX:ParallelGCThreads":指定垃圾收集的线程数量,ParNew默认开启的收集线程与CPU的数量相同;
总结:
描述项 | 具体细节 |
---|---|
特点描述 | 除了垃圾收集采用多线程外,其余的行为、特点和Serial收集器一样 |
应用场景 | 在Server模式下,ParNew收集器是一个非常重要的收集器,因为除Serial外,目前只有它能与CMS收集器配合工作 |
优点 | 随着CPU数量增加,在GC时对资源利用更好 |
Parallel Scavenge收集器也是一个新生代收集器,它也是使用复制算法的收集器,又是并行多线程收集器。parallel Scavenge收集器的特点是它的关注点与其他收集器不同,CMS
等收集器的关注点是尽可能地缩短垃圾收集时用户线程的停顿时间,而parallel Scavenge
收集器的目标则是达到一个可控制的吞吐量。吞吐量= 程序运行时间/(程序运行时间 + 垃圾收集时间),虚拟机总共运行了100分钟。其中垃圾收集花掉1分钟,那吞吐量就是99%。
短停顿时间适合和用户交互的程序,良好的响应速度能提升用户体验。高吞吐量适合高效利用CPU,主要用于后台运算不需要太多交互
参数介绍:
Parallel Scavenge收集器提供两个参数用于精确控制吞吐量; 一个GC自适应参数:
参数 | 描述 |
---|---|
-XX:MaxGCPauseMillis | 控制最大垃圾收集停顿时间,是一个大于0的毫秒数 |
-XX:GCTimeRatio | 设置垃圾收集时间占总时间的比率,0 |
-XX:UseAdaptiveSizePolicy | 当这个参数打开之后,就不需要手工指定新生代的大小、Eden与Survivor区的比例、晋升老年代对象年龄等细节参数了,虚拟机会根据当前系统的运行情况收集性能监控信息,动态调整这些参数以提供最合适的停顿时间或者最大的吞吐量,这种调节方式称为GC自适应的调节策略(GC Ergonomics) |
注:
总结:
描述项 | 具体细节 |
---|---|
特点描述 | 也称为吞吐量收集器(Throughput Collector),新生代收集器;采用复制算法;多线程收集 |
应用场景 | 高吞吐量为目标,即减少垃圾收集时间,让用户代码获得更长的运行时间; 当应用程序运行在具有多个CPU上,对暂停时间没有特别高的要求时,即程序主要在后台进行计算,而不需要与用户进行太多交互 |
GC自适应的调节策略 | JVM会根据当前系统运行情况收集性能监控信息,动态调整这些参数,以提供最合适的停顿时间或最大的吞吐量 |
描述项 | 具体细节 |
---|---|
特点描述 | Serial Old是Serial收集器的老年代版本,它同样是一个单线程收集器,使用标记-整理算法 |
应用场景 | Serial Old收集器的主要意义也是在于给Client模式下的虚拟机使用 |
两大用途:
Concurrent Mode Failure
时使用
Parallel Old是Parallel Scavenge
收集器的老年代版本
,使用多线程
和“标记-整理”
算法。
在JDK 1.6才开始提供的
由于之前有一个Parallel Scavenge
新生代收集器,,但是却无老年代收集器与之完美结合,只能采用Serial Old
老年代收集器,但是由于Serial Old
收集器在服务端应用性能上低下(无法充分利用多CPU资源),其吞吐量反而不一定有PreNew+CMS
组合给力
直到Parallel Old(1.6)收集器出现后,“吞吐量优先”收集器终于有了比较名副其实的应用组合。
应用场景:在注重吞吐量以及CPU资源敏感的场合,都可以优先考虑Parallel Scavenge加Parallel Old收集器
设置参数: “-XX:+UseParallelOldGC”:指定使用Parallel Old收集器;
总结:
描述项 | 具体细节 |
---|---|
特点描述 | 是Parallel Scavenge收集器的老年代版本,它同样是一个多线程收集器,使用标记-整理算法 |
应用场景 | 注重吞吐量以及CPU资源敏感的场景,用Parallel Scavenge 加Parallel Old 组合 |
后记: