垃圾回收器
- 首先,垃圾回收算法有,标记复制、标记清除、标记整理
- 新生代收集器:Serial、ParNew、Parallel Scavenge
- 老年代收集器:Serial Old、Parallel Old、CMS
- 整堆收集器:G1
- JDK1.8默认收集器
- JDK 8默认搜集器为ParrallelGC,即Young区采用Parallel Scavenge,老年代采用Parallel Old进行收集(PS + PO)
- 这套配置的特点是吞吐量优先,一般适用于后台任务型服务器
Serial收集器
- Serial收集器是一种新生代的垃圾收集器,是一个单线程工作的收集器,使用标记复制算法进行回收
- 收集器在工作时必须暂停其他所有工作线程,成为Stop The World(STW)
- SefePoint 全局安全点:它就是代码中的一段特殊的位置,在所有用户线程到达 SafePoint 之后,用户线程挂起,GC 线程会进行清理工作。
- 优缺点:
- 高效简单,所有收集器汇总额外内存消耗最小的
ParNew收集器
- Serial收集器的多线程版本,除了使用多线程外其他参数和机智与Serial完全一致
- STW时,Parnew是多线程回收的,Serial是单线程的
Parallel Scavenge收集器
- 新生代收集器(Java8默认年轻代收集器)
- 基于标记复制算法,而且可以并行收集(多线程)
- Parallel Scavenge与ParNew的区别
- Parallel Scavenge更注重收集器的吞吐量上(用户代码时间/用户代码时间+垃圾手机的时间的值)
Serial Old收集器
- 老年代收集器
- 单线程收集器使用标记整理算法
- Serial Old收集器有两种用途
- 在JDK5和之前的版本与Parallel Scavenge搭配使用
- 作为CMS收集器的备选
Parallel Old收集器
- Parallel Scavenge的老年代版本
- 支持多线程并发收集、基于标记-整理算法
CMS收集器
- 老年代收集器
- 主要目标是获取最短的回收停顿时间
- 基于标记-清除算法、支持并发收集
- 收集流程如下:
- 初始标记,标记GCroots直接关联到的对象,速度很快
- 并发标记,并发标记从GCroots的直接关联对象开始遍历整个对象图。
- 重新标记,检查错误标记或漏掉标记的情况
- 并发清除
- 初始标记与重新标记需要STW
- CMS的缺点
- 在并发阶段会占用一部分应用线程降低吞吐量
- CMS无法处理浮动垃圾
- 浮动垃圾:由于并发标记和并发清理阶段用户线程还在继续运行,这部分产生的垃圾无法处理
- 标记清除会出现大量空间碎片
- CMS回收过程中触发两次STW
- 第一次暂停从root对象开始标记存活的对象,这个阶段称为初始标记;
- 第二次暂停是在并发标记之后, 暂停所有应用程序线程,重新标记并发标记阶段遗漏的对象(在并发标记阶段结束后对象状态的更新导致)
G1收集器
- 全堆收集器
- 面向堆内存的任何部分组成回收堆来组成回收集。
- G1基于Region来进行回收
- Region是堆内存中任意的布局(逻辑概念)。
- 利用化整为零的思路,把内存区域划分成独立区域Region,
- Region中Humongous区域专门用于存储大对象,G1认为只要大小超过Region容量一般的对象可认为大对象,存储在Humongous Region作为老年代
- 运作过程
- 初始标记:仅标记下GCRoots能够直接关联到的对象
- 并发标记,不需要STW
- 最终标记
- 筛选回收
- 负责更新 Region 的统计数据,对各个 Region 的回收价值和成本进行排序。
- 根据用户所期望的停顿时间来制定回收计划,可以自由选择多个 Region 构成回收集,然后把决定要回收的那一部分 Region 存活对象复制到空的 Region 中,再清理掉整个旧 Region 的全部空间。
- 缺点:
- Region中存在跨带引用问题,虽然可以用记忆集解决,但是Region中跨代引用要复制很多
- 如何保证收集线程与用户线程不干扰运行?
- CMS使用增量更新算法
- G1使用原始快照
- G1为Region分配了两块TAMS指针,把Region中一部分划分出来用于并发回收(不会STW)过程中的新对象分配,新对象必须分配在指定的内存区域。如果回收速度赶不上分配速度也会STW,导致full gc
对比G1与CMS回收期的区别
- CMS收集器是老年代的收集器,可以配合新生代的Serial和ParNew收集器一起使用;
- G1收集器收集范围是老年代和新生代,不需要结合其他收集器使用;
- CMS收集器以最小的停顿时间为目标的收集器;
- G1收集器可预测垃圾回收的停顿时间
- CMS收集器是使用“标记-清除”算法进行的垃圾回收,容易产生内存碎片
- G1收集器使用的是“标记-整理”算法,进行了空间整合,降低了内存空间碎片。
ZGC
- JDK11 中加⼊的具有实验性质的低延迟垃圾收集器,⽬标是尽可能在不影响吞吐量的前提下,实现在任意堆内存大小都可以把停顿时间限制在 10ms 以内的低延迟。
- 基于 Region 内存布局,不设分代,使用了读屏障、染色指针和内存多重映射等技术实现可并发的标记整理,以低延迟为首要⽬标。 ZGC 的 Region 具有动态性,是动态创建和销毁的,并且容量⼤⼩也是动态变化的。