Hotspot垃圾收集器组合
图展示了7种作用于不同分代区域的收集器,存在连线表示可以组合使用。
1.Serial/Serial Old
1.1 Serial收集器
这个收集器是一个单线程的收集器,但它的单线程的意思并不仅仅说明它只会使用一个CPU或者一个收集线程去完成垃圾收集的工作,而且在工作的同时,必须暂停掉其他所有线程,直到它收集结束。
虚拟机在后台自动发起和自动完成,在用户不可见的情况下把用户正常工作的线程全部停掉。
它也有优于其他收集器的地方:简单而高效与其他收集器的单线程相比,对于限定单个cpu的环境来说,Serial收集器由于没有线程交互的开销,专心做垃圾收集自然可以获得最高的单线程收集效率。Serial在Client模式下的虚拟机是一个很好的选择。
1.2 Serial Old收集器
Serial Old是Serial 的老年代版本,同样是一个单线程收集器,使用‘标记-整理’算法。
2.ParNew收集器
图为:PraNew/Serial Old
ParNew收集器其实就是Serial收集器的多线程版本,使用多线程进行垃圾收集。ParNew收集器在单CPU的环境中绝对不会比Serial收集器更好的效果,甚至由于存在线程交互开销,该收集器在通过超线程技术实现的两个cpu的环境中都不能100%保证可以超越Serial收集器。随着使用cpu数量的增加,它对GC时系统资源的有效利用还是有好处的。默认开启垃圾收集线程数与CPU数相同,使用-XXl:ParallelGCThreads控制垃圾收集线程数。
名词解释(在垃圾收集器的上下文语境中):
并行(Parallel):指多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态。
并发(Concurrent):用户线程和多条垃圾收集线程同时执行,但不一定是并行的,可能会交替执行,用户程序在继续运行,而垃圾收集线程运行在另一个cpu上。
3.Parallel Scavenage/Parallel Old
3.1Parallel Scavenage收集器
这是一个新生代的收集器,它也是使用的复制算法,而且是并行的多线程收集器,它与ParNew最大的不同是,Parallel Scavenage关注的目标是可控制的吞吐量。
吞吐量= 运行用户代码时间/(运行用户代码时间+垃圾收集时间)。
3.2 Parallel Old收集器
Parallel Old是parallel scavenge的老年代版本,使用多线程和‘标记-整理’算法。
4.CMS收集器
CMS(Concurrent Mark Sweep)收集器是一种以最短回收停顿时间为目标的收集器。从名字可以看出,并发-标记-清理,它的运作过程分为4步:
1.初始标记
这个阶段需要STW(stop the world),仅仅只标记GC Roots能直接关联到的对象,速度很快
2.并发标记
进行GC Roots Tracing(追踪)的过程,从GC Roots开始从堆中对象进行可达性分析,找出存活对象
3.重新标记
这个阶段需要STW(stop the world),为了修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,停顿时间:初始标记<重新标记<并发标记;
4.并发清除
对可回收区域进行清理,可与用户线程一起并发执行。
CMS主要优点:并发收集,低停顿。它有三个缺点
1.CMS收集器对CPU资源非常敏感。在并发阶段虽然不会导致用户线程停顿,但是会占用一部分CPU资源导致应用程序变慢,总吞吐量变低
2.无法处理浮动垃圾,可能出现“Concurrent Mode fail”失败导致一次full GC的产生。由于CMS并发清理阶段用户线程还在运行,CMS无法在当次收集中处理它们,只好在下次gc中处理,这类垃圾称为“浮动垃圾”。
3.“标记-清除”算法导致收集结束产生大量的空间碎片,老年代空间会随着应用时长被逐步耗尽,最后将不得不通过担保机制对堆内存进行压缩。CMS也提供了参数-XX:CMSFullGCsBeForeCompaction(默认0,即每次都进行内存整理)来指定多少次CMS收集之后,进行一次压缩的Full GC。
5.G1收集器
G1是一款面向服务端应用的垃圾收集器。它的使命是替换掉JDK1.5中发布的CMS收集器。特点如下:
1.并行与并发:G1能充分利用多CPU、多核环境下的硬件优势,使用多个CPU来缩短‘stop the world’停顿的时间,部分其他收集器需要停顿java线程执行的GC动作,G1收集器仍然可以通过并发的方式让java用户线程继续执行。
2.分代收集
能采取不同的方式去处理新创建的对象、已经存活一段时间的对象,或者已经熬过多次gc的对象。
3.空间整合
G1从整体来看是基于“标记-整理”算法实现,从局部上基于“复制算法”实现。这两种算法都不会产生空间碎片。
4.可预测的停顿
降低停顿时间是G1和CMS共同关注点,但是G1还能建立可以预测的时间停顿模型,能让使用者明确指定一个长度时间为M毫秒时间段内,垃圾收集时间不超过N毫秒。
G1收集器运作大致可以分为
1.初始标记
仅仅只是标记一下GC Roots能直接关联到的对象,并且修改iTAMS(Next Top at Mark Start)的值,让下一阶段用户程序运行时,能在正确可用的Region中创建对象,这个阶段“stop the world”.
2.并发标记
从GC Roots开始从堆中对象进行可达性分析,找出存活对象,这个阶段耗时较长,但是可以与用户线程并发执行。
3.最终标记
这个阶段是STW(stop the world),是为了修正在并发标记阶段用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,这个阶段标记线程也是并行执行的,通过参数-XX:ParallelGCThread可设置GC暂停时可用的GC线程数。
4.筛选回收
这个阶段是STW(stop the world,在最后的筛选回收阶段对各个Region的回收价值和成本进行排序,根据用户的GC停顿时间来指定回收计划,这个阶段也是并行执行的,从Sun公司的信息来看,这个阶段也可以与用户程序一起并发执行,但是暂停用户线程能极大的提高回收的效率。