《深入理解Java虚拟机》笔记-垃圾收集器-基础篇

JDk1.7 Update 14 之后的HotSpot虚拟机所包含的收集器有:

《深入理解Java虚拟机》笔记-垃圾收集器-基础篇

连线代表收集器之间可以搭配使用。上半区域代表新生代,下半部分代表老年代。下面分别简单介绍上图中的收集器。

1. Serial收集器

单线程收集。必须暂停其他所有工作线程。

是虚拟机运行在Client模式下的默认新生代收集器。

简单高效(和其他收集器的单线程相比),对限定单CPU的环境来说,没有线程交互的开销。

《深入理解Java虚拟机》笔记-垃圾收集器-基础篇

Serial/Serial Old收集器运行示意图

2. ParNew收集器

可以看做是Serial收集器的多线程版本。

是许多运行在Server模式下的虚拟机中首选的新生代收集器。主要原因是,除了Serial收集器外,ParNew是唯一一个能和CMS收集器配合工作的收集器。使用-XX:+UseConcMarkSweepGC选项后的的默认新生代收集器。也可以通过-XX:+UseParNewGC选项来强制指定它。

在单CPU的环境中,ParNew的性能不会比Serial好。随着可使用CPU数量的增加,它对GC时系统资源的有效利用很有好处。默认开启的收集线程数与CPU的数量相同。可以通过-XX:ParallelGCThreads参数来限制垃圾收集器的线程数。

《深入理解Java虚拟机》笔记-垃圾收集器-基础篇

ParNew收集器运行示意图

Parallel Scavenge收集器运行示意图

3. Parallel Scavenge收集器

是一个新生代收集器,也使用复制算法,也是并行的多线程收集器。

目标:达到一个可控制的吞吐量(Throughput)。

吞吐量是CPU用于运行用户代码的时间与CPU运行总时间的比值。即吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)。

高吞吐量可以高效的利用CPU时间,尽快完成程序的运算任务,主要用于在后台运算不需要太多交互的任务。

提供了两个参数用于精准控制吞吐量:-XX:MaxGCPauseMillis和-XX:GCTimeRatio

XX:MaxGCPauseMillis用于控制最大垃圾收集停顿时间。一个大于0的毫秒数。设置太小会使新生代空间减小,吞吐量降低。

XX:GCTimeRatio用于设置吞吐量的大小。一个大于0小于100的整数。是垃圾收集时间占总时间的比例。如果值为19,那允许的最大GC时间就占总时间的5%(1/(1+19))。

另外一个参数比较重要:-XX:+UseAdaptiveSizePolicy。打开这个开关后,设置优化目标(停顿时间或吞吐量),那具体细节的参数调节工作由虚拟机自己完成了。细节参数包括:新生代大小(-Xmn)、Eden与Survivor区的比例(-XX:SurvivorRatio)、晋升老年代对象大小(-XX:PretenureSizeThreshold)等。

《深入理解Java虚拟机》笔记-垃圾收集器-基础篇

Parallel Scavenge/Parallel Old收集器运行示意图

4. Serial Old收集器

是Serial收集器的老年代版本,使用标记整理算法。

主要给Client模式下的虚拟机使用。

如果在Server模式下,有两个用途:在JDK1.5及以前的版本中和Parallel Scavenge收集器搭配时用;作为CMS收集器的候选备案,在并发收集发生Concurrent Mode Failure时使用。

5. Parallel Old收集器

Parallel Scavenge的老年代版本,使用多线程和标记-整理算法。

在JDK1.6中才开始提供。

在注重吞吐量以及CPU资源敏感的场合,都可以考虑使用Parallel Scavenge加Parallel Old收集器。