共计 2615 个字符,预计需要花费 7 分钟才能阅读完成。
备注:基于 JDK1.7 Update 14 之后的版本。
Serial 收集器
Serial 收集器是最根本、倒退历史最悠久的收集器,在 JDK1.3.1 之前是虚拟机新生代收集的惟一抉择。Serial 收集器是一个单线程的收集器,须要留神的是这里的“单线程”并不仅仅阐明它只会应用一个 CPU 或一条收集线程去实现垃圾收集工作,而是它在进行垃圾收集时,必须暂停其余所有的工作线程,直到收集完结。即 Stop The World。收集器运行过程如下:
特点:
简略高效,对于限定单个 CPU 的环境来说,Serial 收集器因为没有线程交互的开销,分心做垃圾收集,天然能够取得最高的单线程收集效率。实用于运行在 Client 模式下的虚拟机。
ParNew 收集器
ParNew 收集器时 Serial 收集器的多线程版本,除了应用多条线程进行垃圾收集之外,其余的行为都与 Serial 收集器齐全一样。ParNew 收集器的示意图如下:
ParNew 收集器实用于运行在 Server 模式下的虚拟机的新生代收集器。并且它可能与 CMS 收集器配合工作。
Parallel Scavenge 收集器
Parallel Scavenge 收集器是一个新生代收集器,应用的时 复制算法,是并行的多线程收集器。Parallel Scavenge 收集器的指标是达到一个可管制的吞吐量。吞吐量指的是 CPU 用于运行用户代码的工夫与 CPU 总耗时工夫的比值,即:
吞吐量 = 运行用户代码工夫 /(运行用户代码工夫 + 垃圾收集工夫)。
比方,虚拟机总共运行了 100 分钟,其中垃圾收集花掉 1 分钟,吞吐量就是 99%。
进展工夫越短就越适宜须要与用户进行交互的程序,良好的响应速度能晋升用户体验,而高吞吐量则能够高效地利用 CPU 工夫,尽快实现程序的运算工作,次要实用于后盾运算而不须要太多交互的工作。
Serial Old 收集器
Serial Old 收集器是 Serial 收集器的老年代版本,也是一个单线程收集器,应用“标记—整顿”算法。示意图如下:
该收集器也是给 Client 模式下的虚拟机应用。如果是在 Server 模式下,还能够有两个用处:
- 在 JDK1.5 以及之前版本中与 Parallel Scavenge 收集器搭配应用;
- 作为 CMS 收集器的后备预案,在并发收集产生 Concurrent Mode Failure 时应用。
Parallel Old 收集器
Parallel Old 是 Parallel Scavenge 收集器的老年代版本,应用多线程和“标记—整顿”算法。示意图如下:
CMS 收集器
CMS 收集器是一种以获取最短回收进展工夫为指标的收集器。是基于“标记—革除”算法实现的。它的运作过程分为 4 个步骤:
- 初始标记
初始标记须要“Stop The World”。初始标记仅仅只是标记一下 GC Roots 能间接关联到的对象,速度很快。 - 并发标记
并发标记阶段就是进行 GC Roots Tracing 的过程。 - 从新标记
从新标记阶段须要“Stop The World”。该阶段是为了修改并发标记期间因用户程序持续运作而导致标记产生变动的那一部分对象的标记记录,这一阶段的进展工夫个别会比初始标记阶段稍长一些,但比并发标记的工夫短。 - 并发革除
该阶段是对被标记的对象进行革除,回收内存。
示意图如下:
长处:并发收集,低进展。
毛病:
- CMS 收集器对 CPU 资源十分敏感。
- CMS 收集器无奈解决浮动垃圾,可能呈现“Concurrent Mode Failure”失败而导致另一次 Full GC 的产生 。在 JDK1.5 的默认设置下,CMS 收集器当老年代应用了 68% 的空间后就会激活,如果在利用中老年代增长不是太快,能够适当调高参数-XX:CMSInitiatingOccupancyFraction 的值来进步触发百分比,以便升高内存回收次数从而取得更好的性能。在 JDK1.6 中,CMS 收集器的启动阈值曾经晋升至 92%。
- CMS 是基于“标记—清理”算法实现的,收集完结时可能会有大量碎片空间产生。空间碎片过多时,将会给大对象的调配造成很大的麻烦,往往会呈现老年代还有很大的残余空间,然而无奈调配以后对象,不得不提前触发一次 Full GC。为了解决这个问题,CMS 收集器提供了一个开关参数:-XX:+UseCMSCompactAtFullCollection,该参数默认是开启的,用于在 CMS 顶不住要进行 Full GC 是开启内存碎片的合并整顿过程。
G1 收集器
G1(Garbage-First)收集器是一款面向服务端利用的垃圾收集器。具备如下特点:
- 并行与并发
- 分代收集
- 空间整顿
- 可预测的进展
G1 收集器将整个 Java 堆划分为多个大小相等的独立区域(Region),尽管还保留有新生代和老年代的概念,但新生代和老年代不再是物理隔离的了,他们都是一部分不须要间断的 Region 的汇合。
在 G1 收集器中,Region 之间的对象援用以及其余收集器中的新生代与老年代之间的对象援用,虚拟机都是应用 Remembered Set 来防止全堆扫描。G1 中每一个 Region 都有一个与之对应的 Remembered Set,虚拟机发现程序在 Reference 类型的数据进行写操作时,会产生一个 Write Barrier 临时中断写操作,查看 Reference 援用的对象是否处于不同的 Region 之中,如果是,便通过 CardTable 把相干援用信息记录到被援用对象所属的 Region 的 Remembered Set 即可保障不对全堆扫描也不会有脱漏。
G1 收集器的运作大抵可划分为以下几个步骤:
- 初始标记
初始标记阶段仅仅只是标记一下 GC Roots 能间接关联到的对象,并且批改 TAMS(Next Top at Mark Start)的值,让下一阶段用户程序并发运作时,能在正确可用的 Region 中创立新对象,这一阶段须要进展线程,但耗时很短。 - 并发标记
并发标记阶段是从 GC Root 开始对堆中的对象进行可达性剖析,找出存活的对象,这一阶段耗时较长,然而能够和用户线程并发执行。 - 最终标记
最终标记是为了修改在并发标记期间因用户程序继续执行而导致标记产生变动的那一部分标记记录,虚拟机将这段时间对象变动记录在线程 Remembered Set Logs 外面,最终标记阶段须要把 Remembered Set Logs 的数据合并到 Remembered Set 中,这一阶段须要进展线程,然而能够并行执行。 - 筛选回收
筛选回收阶段首先对各个 Region 的回收价值和老本进行排序,依据用户所冀望的 GC 工夫来指定回收打算。
G1 收集器的运行示意图如下: