深入理解JVM3 - 垃圾收集器1
之前说到的垃圾收集算法是内存回收的方法论,那么现在所说的垃圾收集器则是内存回收的具体实现。Java虚拟机规范对于垃圾收集器的实现没有任何规定,因此不同厂商,不同版本的虚拟机所提供的垃圾收集器都可能会有很大差别,并且一般都会提供参数供用户根据自己的应用特点和要求组合各个年代所使用的收集器。
HotSpot虚拟机的垃圾收集器-
Serial收集器
Serial收集器是最基本、发展历史最悠久的收集器,曾经是虚拟机新生代收集的唯一选择。Serial收集器是一个单线程的收集器,不仅只会使用一个CPU和线程,而且在垃圾收集的时候会暂停其他所有的工作线程,直到它收集结束。这就是所谓的“Stop The World”,在用户不可见的情况下把用户正常工作的线程全部停掉,这对很多应用来说可能都是难以接受的。但是Serial收集器有着简单高效的优点,对于限定单个CPU的环境来说,Serial收集器由于没有线程交互的开销,专心做垃圾收集自然可以获得最高的单线程收集效率。目前Serial收集器主要运行在client模式的Java虚拟机中。用于收集新生代的内存。
Serial收集器运行过程 -
ParNew收集器
ParNew收集器是Serial收集器的多线程版本,除了使用多条线程进行垃圾收集之外,其余行为包括Serial收集器可用的所有控制参数、收集算法、Stop The World、对象分配规则、回收策略都与Serial收集器完全一样。
目前ParNew收集器是运行在Server模式下虚拟机的首选新生代垃圾收集器。
-
Parallel Scavenge收集器
Parallel Scavenge收集器是一个新生代收集器,它也是使用复制算法的收集器,又是并行的多线程收集器,特点是Parallel Scavenge收集器目标是达到一个可控制的吞吐量(Throughput),而其他收集器的关注点则是尽可能的减少垃圾收集时用户线程的停顿时间。吞吐量就是CPU用户运行用户代码的时间与CPU总消耗时间的比值,即 吞吐量 = 运行用户代码时间 / (运行用户代码时间+ 垃圾收集时间)。停顿时间越短就越适合需要与用户交互的程序,具有良好的响应速度,能够提升用户体验;而高吞吐量则可以高效率的利用CPU时间,尽快完成程序的运算任务,主要适合在后台运算而不太需要交互的任务。 -
Serial Old收集器
Serial Old是Serial收集器的老年代版本,它同样是一个单线程收集器,使用标记-整理算法。主要意义还是给Client模式下的虚拟机使用。
Serial Old收集器工作流程 -
Parallel Old收集器
Parallel Old是Parallel Scavenger收集器老年代版本,使用多线程和标记整理算法。该收集器从JDK 1.6开始提供,再次之前新生代的Parallel Scavenger收集器一直处于比较尴尬的状态。原因是如果新生代是Parallel Scavenger收集器,则老年代除了Serial Old之外别无选择,因为Parallel Scavenger收集器和CMS收集器(之后会介绍该收集器)无法配合工作。由于Serial Old在服务端性能上的“拖累”,使用了Parallel Scavenger收集器也未必能获得最大化的吞吐量。单线程的Serial Old收集器无法利用服务器端多CPU的处理能力,导致吞吐量不佳。而Parallel Old出现后,就可以和Parallel Scavenger收集器搭配使用,使用与注重吞吐量以及CPU资源敏感的场合。
Parallel Old收集器