再了解完新生代的垃圾收集器后,我们再来了解下老年代的垃圾收集器
一、Serial Old 收集器
-
Serial Old 收集器是 Serial 收集器的老年代版本,它同样是一个单线程收集器,采用标记-整理算法
-
在程序启动的时候,通过使用 -XX:UseSerialOldGC 参数来指定老年代使用 Serial Old 收集器来进行回收
-
单线程,进行垃圾收集时,必须暂停所有工作线程
-
简单高效,是 Client 模式下默认的老年代收集器
-
Serial Old 主要用于 Client 模式,当用于 Server 模式时,有两大用途
-
在 JDK5 及之前的版本中与 Parallel Scavenge 收集器搭配使用
-
作为 CMS 收集器的后备预案
-
-
二、Parallel Old 收集器
-
Parallel Old 收集器是 Parallel Scavenge 收集器的老年代版本,它同样是一个多线程收集器,采用标记-整理算法
-
在程序启动的时候,通过使用 -XX:UseParallelOldGC 参数来指定老年代使用 Parallel Old 收集器来进行回收
-
多线程,吞吐量优先
-
在注重吞吐量以及 CPU 资源敏感的场合,可以优先考虑 Parallel Scavenge 收集器加 Parallel Old 收集器的组合
-
三、CMS 收集器
-
CMS (Concurrent Mark Sweep) 收集器是一种以获取最短回收停顿时间为目标的收集器,采用标记-清除算法 (会带来内存碎片化的问题)
-
在程序启动的时候,通过使用 -XX:UseConcMarkSweepGC 参数来指定老年代使用 CMS 收集器来进行回收
-
CMS 收集器的运作过程可以分为以下几步
-
初始标记
-
需要暂停虚拟机 (stop-the-world)
-
该过程从垃圾回收的根对象 (GC Roots) 开始,只扫描到与根对象直接关联的对象并作标记,速度很快
-
-
并发标记
- 并发追溯标记,程序不会停顿,即收集线程与用户线程并发执行
-
并发预清理
- 查找执行并发标记阶段从新生代晋升到老年代的对象或直接被分配到老年代的对象,通过重新扫描,减少下一个阶段重新标记的工作
-
重新标记
-
需要暂停虚拟机 (stop-the-world),扫描 CMS 堆中剩余的对象
-
扫描从根对象开始向下追溯,并处理对象关联
-
目的在于修正并发标记期间用户程序继续运作而导致标记产生变动的那一部分对象的标记记录
-
-
并发清理
- 清理垃圾对象,程序不会停顿,即收集线程与用户线程并发执行
-
并发重置
- 重置 CMS 收集器的数据结构,等待下一次垃圾回收
-
-
四、G1 收集器
-
G1 (Garbage First) 收集器是当今收集器技术发展的最前沿成果之一,是一款面向服务端应用的垃圾收集器,既可用于新生代,又可用于老年代,采用复制 + 标记-整理算法
-
在程序启动的时候,通过使用 -XX:UseG1GC 参数来指定老年代使用 G1 收集器来进行回收
-
与其他收集器相比,G1 收集器具备以下特点
-
并行与并发
- 充分利用多 CPU、多核环境下的硬件优势,使用多个 CPU 来缩短 stop-the-world 停顿的时间,与用户线程并发执行
-
分代收集
- 不需要其他收集器配合就能独立管理整个 GC 堆,但它能够采用不同的方式去处理新创建的对象和已经存活了一段时间、熬过多次 GC 的旧对象以获取更好的收集效果
-
空间整合
- 基于标记-整理算法,解决了内存碎片的问题,收集后能提供规整的可用内存
-
可预测的停顿
- 可以建立可预测的停顿时间模型,能让使用者明确指定在一个长度为 M 毫秒的时间片段内,消耗在垃圾收集上的时间不得超过 N 毫秒
-
-
-
在 G1 之前的其他收集器进行收集的范围都是整个新生代或者老年代,而 G1 不再是这样。使用 G1 收集器时, Java 堆的内存布局与其他收集器有很大的区别,它将整个 Java 堆划分为多个大小相等的独立区域 (Region),虽然还保留有新生代和老年代的概念,但新生代和老年代不再是物理隔离了,它们都是一部分独立区域 (不需要连续) 的集合
五、归纳总结
-
Serial Old 收集器
-
采用标记-整理算法,单线程收集
-
程序启动时,可以通过
-XX:UseSerialOldGC参数来指定老年代使用 Serial Old 收集器来进行回收 -
是 Clinet 模式下默认的老年代收集器
-
-
Parallel Old 收集器
-
采用标记-整理算法,多线程收集
-
更关注系统的吞吐量
-
是 Server 模式下默认的老年代收集器
-
-
CMS 收集器
-
采用标记-清除算法,多线程收集,以获取最短回收停顿时间为目标
-
程序启动时,可以通过
-XX:UseConcMarkSweepGC参数来指定老年代使用 CMS 收集器来进行回收
-
-
G1 收集器
-
采用复制 + 标记-整理算法,多线程收集,既可用于新生代,又可用于老年代
-
程序启动时,可以通过
-XX:UseG1GC参数来指定老年代使用 G1 收集器来进行回收
-