常用垃圾收集器:G1,CMS等

Serial收集器

单线程的收集器,它的单线程的意义不仅仅说明它只会使用一个CPU或一条收集线程去完成垃圾收集工作,更重要的是在它进行垃圾收集时,必须暂停其他所有的工作线程,直到它收集结束。

Serial在新生代使用复制算法。Serial Old在老生代使用标记-整理算法。

虽然到后期的垃圾收集器,用户线程的停顿时间在不断缩短,但是仍然没有办法完全消除。

到目前为止,Serial收集器仍然是虚拟机运行在Client模式下的默认新生代收集器。

ParNew收集器

Serial收集器的多线程版本。
ParNew收集器是许多运行在Server模式下的虚拟机中首选的新生代收集器,其中有个预性能无关但很重要的原因是,除了Serial收集器外,目前只有它能与CMS收集器配合工作。CMS收集器是Hotspot虚拟机中第一款真正意义上的并发收集器,第一次实现了让垃圾收集线程与用户线程(基本上)同时工作。但是CMS作为老年代收集器却无法与JDK 1.4已经存在的新生代收集器Parallel Scavenge配合工作。

ParNew收集器是使用-XX:+UseConcMarkSweepGC选项后的默认新生代收集器,也可以使用-XX:+UserParNewGC选项来强制指定它。

ParNew在单CPU环境中绝对不会有比Serial收集器更好的效果,甚至存在由于线程交互的开销。

Parallel Scavenge收集器

新生代收集器,也是使用复制算法、并行的多线程收集器。它的特点是关注点与其他收集器不同,CMS等收集器关注点是尽可能地缩短垃圾收集时用户线程的停顿时间,而Parallel Scavenge收集器的目的是达到一个可控制的吞吐量(Throughput)。所谓吞吐量是CPU用于运行用户代码的时间与CPU总消耗时间的比值。

停顿时间越短就越适合需要与用户交互的程序,良好的响应速度能提升用户体验,而高吞吐量则可以高效率地利用CPU时间,尽快完成程序的运算任务,主要适合在后台运算而不需要太多交互的任务。

该收集器提供了两个参数用于精确控制吞吐量。

  • -XX:MAXGCPauseMillis:控制最大垃圾收集停顿时间
  • -XX:GCTimeRatio:直接设置吞吐量大小

Parallel Old是它在老年代的版本,使用多线程和标记-整理算法。

CMS收集器

Current Mark Sweep,一种以获取最短回收停顿时间为目标的收集器。基于标记-清除算法实现。整个过程分为四步:

  • 初始标记
  • 并发标记
  • 重新标记
  • 并发清除

初始标记和重新标记仍需要Stop The World。初始标记仅仅是标记一下GC Roots能直接关联到的对象,速度很快。并发标记就是进校GC Roots Tracing的过程,而重新标记阶段则是为了修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录。这个阶段的停顿时间一般会比初始标记阶段稍长一些,但远比并发标记时间短。

CMS是一款优秀的收集器,但是3个缺点:

  • 对CPU资源非常敏感
  • 无法处理浮动垃圾
  • 是一款基于标记-清除算法的收集器,会有空间碎片产生

G1收集器(Garbage First)

并行与并发
分代收集
空间整合:G1整体来看是标记-整理,局部来看是基于复制算法。
可预测的停顿

大致分为以下几步:

  • 初始标记
  • 并发标记
  • 最终标记
  • 筛选回收