如下图所示,若两个收集器之间存在连线,说明它们可以搭配使用。
Serial收集器是最基本的,发展历史最悠久的收集器,是一个单线程的收集器,只会使用一个CPU或一条收集线程去完成垃圾收集工作,而且在进行垃圾收集时,必须暂停其他所有的工作线程,直到它收集结束。
暂停其他所有的工作线程,这个过程被称为“Stop The World”,由虚拟机在后头自动发起和自动完成,在用户不可见的情况下把用户正常工作的线程全部停止。
Serial收集器的优点是简单高效。
ParNew收集器是Serial收集器的多线程版本,使用多条线程进行垃圾收集,其他都与Serial收集器一样。
Parallel Scavenge收集器是使用复制算法的,并行多线程收集器。该收集器的特点是达到一个可控制的吞吐量(吞吐量优先),吞吐量是CPU用于运行用户代码时间与CPU总消耗时间的比值,即吞吐量=运行用户代码时间/(运行用户代码时间+垃圾回收时间)。
吞吐量高可以高效的利用CPU时间,尽快完成程序的运算任务,主要适合后台运算多而不需要太多交互的任务。
Parallel Scavenge收集器提供了两个参数精确控制吞吐量,分别是控制最大垃圾收集停顿时间的-XX:MaxGCPauseMillis
参数,以及直接设置吞吐量大小的-XX:GCTimeRatio
参数。
参数-XX:UseAdaptiveSizePolicy
,打开这个参数,虚拟机会根据当前系统的运行情况收集性能监控信息,动态调整各种参数以提高最适合的停顿时间或最大的吞吐量。
Serial Old是Serial收集器的老年代版本,也是单线程的收集器,使用“标记-整理”算法。
在Server模式下,它主要有两个用途:一是在JDK1.5及以后的版本中,与Parallel Scavenge收集器搭配使用;二是作为CMS收集器的后备预案,在并发收集发生Concurrent Mode Failure时使用。
Parallel Old是Parallel Scavenge收集器的老年代版本,使用多线程和“标记-整理算法”
CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。基于“标记-清除”算法实现。
垃圾收集过程主要分为四个阶段:
初始标记
并发标记
重新标记
并发清除
初始标记、重新标记仍需要“Stop The World”,初始标记只标记GC roots 能直接关联的对象,速度快;并发标记就是进行GC Roots Tracing的过程,重新标记是为了修正并发标记期间,因用户程序继续运行,而导致标记发生变动的那部分对象的标记记录,这个阶段的停顿时间一般比初始标记稍长,但远比并发标记时间短。
CMS优点:并发收集,低停顿
CMS缺点:
(1)对CPU资源敏感。面向并发设计的程序都对CPU资源比较敏感。在并发阶段,虽然不会导致用户线程停顿,但是因为占用了一部分线程(CPU资源)而导致应用程序变慢总吞吐量会降低。
(2)无法处理浮动垃圾,可能会出现“Concurrent Mode Failure”失败而导致另一次Full GC。
因为并发清除阶段,用户线程还在运行,就可能会有新的垃圾产生,这部分垃圾出现在标记过程之后,只能留待下次GC回收,这部分垃圾称为“浮动垃圾”。
(3)产生大量空间碎片,因为使用的是标记-清除算法。
G1(Garbage-First)收集器是面向服务端应用的垃圾收集器。
优势:
(1)并行与并发:充分利用多CPU,多核的优势,使用多个CPU来缩短Stop The World停顿时间。部分原本需要停顿java线程执行GC动作,G1收集器仍然可以使用并发的方式让java程序继续运行。
(2)分代收集:而且可以不需要其他收集器配合就能独立管理整个GC堆。
(3)空间整合:G1整体上是基于标记-整理算法实现,从局部(两个region之间)来看是基于复制算法实现,这意味着G1运行期间不会产生内存碎片。
(4)可预测停顿:这是相比CMS的一大优势,G1不仅能降低停顿时间,而且还能建立可预测停顿时间模型,指定在一个长度为M毫秒的时间片内,GC收集时间不得超过N毫秒。
G1垃圾收集过程:
初始标记
并发标记
最终标记
筛选回收
初始标记,标记GC Roots直接关联的对象,并修改TAMS(Next Top at Mark Start)的值,让下一阶段用户程序并发运行时,能在正确的region(在使用G1收集器时,将java堆划分为多个大小相等的独立区域[region],虽然还保留新生代,老年代的概念,但两者不再是物理隔离了,它们都是一部分region[不需要连续]的集合)中创建新对象,这阶段需要停顿线程,但耗时很短。
并发标记从GC Roots开始对堆中对象进行可达性分析,找出存活对象,这阶段耗时较长,但可与用户线程并发执行。
最终标记修正在并发标记期间,因用户线程继续运行而导致的标记产生变动的那部分标记记录,虚拟机将这段时间对象变化记录在线程Remembered Set Logs里,最终标记时,将Remembered Set Logs的数据合并到Remembered Set 中,这阶段需要停顿线程,但可以并行执行。
筛选回收时,对各个region的回收价值(可回收的内存大小)和成本(回收耗费的时间)进行排序,根据用户期望的GC停顿时间制定回收计划。
note:注意在讨论垃圾收集器的上下文语境中
并行(Parallel):指多条垃圾收集线程并行工作,但此时用户线程仍处于等待状态。
并发(Concurrent):指用户线程与垃圾收集线程同时执行(不一定是并行,可能是交替执行),用户程序在继续运行,而垃圾收集程序运行于另一个CPU上。