1.Serial收集器
优点,是简单而高效,单线程避免了线程交互的开销.
缺点,进行垃圾回收时需要Stop the world(暂停所有用户线程).
2.ParNew收集器
它是Serial收集器的多线程版本,新生代才有多线程并行收集.是CMS收集器(下文会介绍)的默认新生代收集器.
ParNew在单CPU的情况下,会比Serial收集器效率更差,因为多线程交互的开销.
但是,如今的计算机普遍是多CPU多核,而ParNew默认的线程数量是CPU的数量.因此它更加适应潮流.
3.Parallel Scavenge收集器
它是一个追求吞吐量的收集器.
吞吐量 = 运行用户代码时间 / (运行用户代码时间 + 垃圾收集时间)
可以通过-XX:GCTimeRatio参数来设置希望达到的吞吐量.
Parallel Scavenge收集器会根据实际运行情况,自适应调整新生代Eden:Survivor的比例,意在达到目标吞吐量.
4.Serial Old收集器
它是Serial收集器的老年代版本,使用标记整理算法.主要意义在于给Client模式下的虚拟机使用.
Server模式下,在JDK1.5和以前的版本配合Parallel Scavenge收集器搭配使用.
另外,Serial Old收集器也是CMS收集器的预备方法,当出现Concurrent Mode Failure时使用.
5.Parallel Old收集器
它是Parallel Scavenge收集器的老年代收集器,使用多线程标记整理算法.
6.CMS(Concurrent Mark Sweep)
它追求的是低停顿时间,适合注重服务响应速度的场景,比如互联网网站B/S系统的Server端上.
CMS是基于标记清除算法的,分成4个步骤:
1.初始标记(CMS Initial Mark)
需要暂停用户线程,标记Root能直接关联到的对象,速度很快耗时很短.
2.并发标记(CMS Concurrent Mark)
无需暂停用户线程,进行Root Tracing的过程
3.重新标记(CMS Remark)
需要暂停用户线程,为了修正并发标记期间因为用户线程继续运行而产生标记变动的那一部分对象的标记记录.
这个阶段的停顿时间一般会比初始标记阶段稍长,但远比并发标记时间短.
4.并发清除(CMS Concurrent Sweep)
CMS收集器的缺点是:
1)吞度量降低了;
2)无法清除浮动垃圾(因垃圾回收阶段,用户线程执行产生的垃圾);
3)标记清除算法会产生内存碎片.
7.G1收集器
G1收集器是最先进最前沿的垃圾收集器,特点:
1.并行与并发,和CMS收集器类似;
2.分代收集.G1能独立管理整个Java堆的垃圾收集;
3.空间整合,不产生内存碎片.从整体看,G1是基于标记整理算法,从局部(两个Region之间)上来看是基于复制算法;
4.可预测的停顿.
G1收集器把整个Java堆划分成多个大小相等的独立区域(Region).G1跟踪每个Region的垃圾堆积的价值大小(回收所获得空间和回收耗时的经验值).
在后台维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的Region(Garbage-First的名称由来).
G1收集器执行步骤:
1.初始标记(Initial Marking)
2.并发标记(Concurrent Marking)
3.最终标记(Final Marking)
4.筛选回收(Live Data Counting and Evacuation)
前面3个步骤都和CMS收集器类似.最后一步的筛选回收中,G1收集器首先对各个Region的回收价值和成本进行排序,根据用户期望停顿时间来制定回收计划.
从Sun公司透露出来的信息来看,筛选回收阶段其实也可以做到与用户程序一起并发执行,但是因为只回收一部分Region,时间是用户可控.
而且停顿用户线程将大幅提高收集效率,所以采用暂停用户程序并行执行筛选回收的方案.