上一节介绍了垃圾回收算法,垃圾收集器是垃圾回收算法的具体实现。
这里以常见的垃圾收集器的组合方式进行介绍:
Serial(年轻代)和Serial Old(老年代)
Serial是年轻代的垃圾收集器,采用单线程的复制算法;垃圾收集期间需要暂停用户线程,直到垃圾收集完毕;在单个CPU环境下由于没有线程交互开销,可以获得最高的单线程垃圾收集效率;该收集器历史较久远。
Serial Old是和Serial配套的老年代的垃圾收集器,采用单线程的标记整理算法。该收集器也是CMS收集器的后备方案。ParNew(年轻代)和CMS(老年代)
ParNew垃圾收集器可以认为是Serial 收集器的多线程版本,也是使用的复制算法;默认开启和CPU数目相同的线程数。
CMS是和ParNew配套的老年代的垃圾收集器,采用的标记清除算法,因此CMS的垃圾回收停顿时间很短。这对垃圾收集器组合适合一些对用户体验要求比较高的程序。但由于标记清除会产生内存碎片,所以当到达一定程度,会启动Serial Old这个垃圾收集器来整理内存碎片,一旦启动Serial Old,这时候的STW会比较长,尤其在大内存时,因此这一点也需要注意。Parallel Scavenge(年轻代)和Parallel Old(老年代)
Parallel Scavenge也是采用复制算法的多线程的垃圾收集器,但是和ParNew的设计上的区别是该垃圾收集器追求高的吞吐量,这里的吞吐量指的是 运行用户代码的时间/(运行用户代码的时间+垃圾收集时间),因此这个垃圾收集器是让cpu用更多时间运行用户代码,因此这个收集器适合计算密集型的服务。
Parallel Old是和Parallel Scavenge配套的老年代的垃圾收集器,采用标记整理算法,保证吞吐量优先。G1
JDK1.8推出的垃圾收集器,相对于其他垃圾收集器, 它有以下特点:
a. 基于标记整理算法,不产生内存碎片;
b. 可以非常精确的控制停顿时间,在不牺牲吞吐量的前提下,实现低停顿的垃圾回收。
c. 在实现上G1避免了全区域垃圾收集,它把对堆内存划分为固定的几个独立区域,并且跟踪这些区域的垃圾收集进度,同时在后台维护一个优先级列表,每次根据所允许的收集时间,优先回收垃圾最多的区域。区域划分和优先级区域回收机制,确保 G1 收集器可以在有限时间获得最高的垃圾收集效率。