四种垃圾收集算法及其特点
标记-清除
流程
- 先标记所有需要回收的对象
- 标记完后统一回收
图示
缺点
- 效率问题
- 空间问题(容易产生大量不连续碎片)
复制算法
流程
- 将内存分大小相同的两块,每次使用其中一块
- 这块使用完后,将存活的对象复制到另一块中
- 把这块全部清空
- 每次的内存回收都是对内存空间的一半进行回收
图示
标记-整理
根据老年代特点提出
流程
- 先标记所有需要回收的对象
- 将对象向一端移动
- 清理端边界以外的内存
图示
分代收集
流程
- 根据对象的存活周期的不同将内存分为几块
- 将堆分为新生代、老年代
- 根据各代的特点选择合适的收集算法
- 如新生代使用复制算法,老年代使用标记-清除或标记-整理
垃圾收集器
Serial(串行)
介绍
- 单线程、STW(Stop The World:暂停其他所有线程)
- 新生代使用复制算法,老年代使用标记-整理
特点
- 简单高效
GC过程
ParNew
介绍
- Serial的多线程版本
- 新生代使用复制算法,老年代使用标记-整理
特点
- 能与CMS配合工作
GC过程
Parallel Scavenge
介绍
- 提供许多参数给用户找到最合适的停顿时间或最大吞吐量
- 新生代使用复制算法,老年代使用标记-整理
特点
- 关注吞吐量,高效利用CPU
- GC过程
Serial Old
介绍
- Serial的老年代版本,单线程
- jdk1.5以前与Parallel Scavenge搭配
- 作为CMS的后备方案
Parallel Old
介绍
- Parallel Scavenge的老年代版本
- 使用多线程和标记-整理
CMS
介绍
- 使用标记-清除
特点
- 获取最短回收停顿时间,注重用户体验
- 低停顿、并发收集
收集步骤
- 初始标记:暂停所有其他线程,并记录下直接与root相连的对象,速度很快
- 并发标记:同时开启GC和用户线程,用一个闭包结构去记录可达对象。但此阶段结束后,不能保证包含当前所有的可达对象,因为用户线程可能会更新
- 重新标记:修正并发标记期间因用户程序继续运行导致更新的标记记录,停顿时间稍长,但远比并发标记短
- 并发清除:开启用户线程,同时GC线程开始对标记区域进行清除
- GC过程
G1
介绍
- 并行与并发:充分利用CPU、多核,缩短STW时间
- 分代收集
- 整体基于标记-整理,局部基于复制算法
- 可预测的停顿:指定时间段内进行GC
特点
- 面向服务器
- 低停顿、高吞吐量
- 在后台维护一个优先列表,每次根据允许的收集时间,优先选择回收价值最大的区域
收集步骤
- 初始标记
- 并发标记
- 最终标记
- 筛选回收