JVM 垃圾收集器介绍
G1
生产目的是为了替换 GMS,将内存化整为零,分成多个独立的 Region,每一个 Region 设计了两个名为 TAMS 的指针。
- 优点:
并行并发:能充分利用 CPU,多核环境下的硬件优势;
分代收集:采用不同方式去处理新生代和老年代,且不需要与其他收集器合作;
空间整合:G1 在整体上是基于标记整理算法的,局部(两个 Region 之间)上是基于复制算法的;
可预测的停顿:G1 能建立可预测的时间停顿模型,能让使用者指定一个长度为 m 毫秒的时间片段,在这个时间片段中停顿不超过 n 毫秒。 - 缺点:
G1 需要卡表来记录新生代和老年代之间的引用关系,需要占用大量内存,所以 G1 适用于大内存的应用场景。
GC 过程分为四步:
- 初始标记:仅仅只是标记以下 GC Roots 能直接关联到的对象,并且修改 TAMS 指针的值,让下一阶段用户线程并发时能正确地在可用的 Region 中分配对象,需要停顿其他线程,但时间很短;
- 并发标记:从 GC Roots 开始对堆中对象进行可达性分析,递归扫描整个堆里的对象图,找出要回收的对象并标记,时间长但不停止其他线程。当对象图扫描完后,还需要重新处理 SATB(原始快照)记录下的在并发时有引用变动的对象;
- 最终标记:对用户线程做另一个短暂的暂停,用于处理并发标记阶段结束后仍遗留下来的最后那少量的 SATB 记录;
- 筛选回收:更新 Region 的统计计数,对各个 Region 的回收价值和成本进行排序,根据用户所期望的停顿时间来制定回收计划,可选择任意多个 Region 构成回收集,把回收集中 Region 的存活对象复制到空的 Region 中,再清理掉整个旧的 Region 空间。操作设计存活对象的移动必须暂停用户线程;
CMS
多线程,基于标记清除算法实现,以获取最短停顿回收时间为目标。
- 优点:停顿时间短;
- 缺点:对 CPU 资源要求高,无法收集浮动垃圾,容易产生大量内存碎片,进而触发 Full GC;
适用于网站或浏览器的 B/S 系统的服务端等用户交互多的场景。
垃圾回收过程分为四步:
- 初始标记:标记 GC Roots 可以直接关联到的对象,需要暂停所有其他线程,但停顿时间很短;
- 并发标记:从 GC Roots 的直接关联对象开始遍历整个对象图,耗时长但不需要停顿其他线程;
- 重新标记:修正并发标记期间因用户程序继续运作而导致标记产生变动的标记记录,需要暂停所有其他线程;
- 并发清除:清除所有标记阶段判定已死亡的对象。
Serial
最基本、发展历史最久的垃圾收集器,新生代采用复制算法,老年代使用标记整理算法。
- 优点:单线程收集,简单高效;
- 缺点:进行 GC 时必须暂停其他所有工作线程;
适用于 Client 模式(桌面应用)和单核服务器。
ParNew
Serial 的多线程版本,新生代采用复制算法,老年代使用标记整理算法。
- 优点:可以更有效地利用系统资源;
- 缺点:进行 GC 时必须暂停其他所有工作线程;
Serial Old
Serival 的老年代版本,单线程,使用标记整理算法,优劣势和 Serival 差不多。
Parallel Scavenge
采用复制算法,多线程,目的是为了达到一个可控制的吞吐量,通过提高收集频率,使得每次停顿时间变短。
- 优点:高吞吐量,高效利用 CPU;
- 缺点:不考虑缩短总的停顿时间。
主要适合在后台运算而不需要太多交互的分析任务。
Parallel Old
Parallel Scavenge 的老年代版本,多线程,使用标记整理算法,优劣势与 Parallel Scavenge 相同。
