JVM学习笔记——GC垃圾收集器

时间:2023-03-09 09:27:10
JVM学习笔记——GC垃圾收集器

GC 垃圾收集器

  Java 堆内存采用分代回收算法,因此 JVM 针对新生代和老年代提供了多种垃圾收集器。

1. Serial 收集器

  Serial 收集器是单线程收集器,采用复制算法

  是最基本的垃圾收集器,只会使用一个 CPU 或一条线程去完成垃圾收集工作,在垃圾收集时必须停止其他工作线程知道垃圾收集结束。

  • 单线程收集器

  • 使用复制算法

  • 收集时需要暂停其他所有线程

  • 简单高效,没有线程交互开销,垃圾收集效率最高

  • 是 JVM 在 Client 模式下默认的新生代垃圾收集器

2. Serial Old 收集器

  是 Serial 收集器的老年代版本

  • 单线程收集器

  • 使用标记整理算法

  • 收集时需要暂停其他所有线程

  • 是 JVM 在 Client 模式下默认的老年代垃圾收集器

  • 是 JVM 在 Server 模式下 CMS 的后备收集方案

3. ParNew 收集器

  ParNew 垃圾收集器是 Serial 的多线程版本,也采用复制算法,其余行为和 Serial 完全一样。

  • 多线程收集器

  • 使用复制算法

  • 收集时需要暂停其他线程

  • 默认开启和 CPU 数目相同的线程数,通过-XX:ParallelGCThreads参数设置线程数

  • 是 JVM 在 Server 模式下默认的新生代垃圾收集器

4. Prarllel Scavenge 收集器

  Prarllel Scavenge 收集器是一个新生代垃圾收集器,采用复制算法,是一个多线程的垃圾收集器,它的侧重点是程序达到可控的吞吐量,高吞吐量可以最高效率的利用 CPU 资源。

  • 多线程收集器

  • 使用复制算法

  • 注重提高系统吞吐量,提高 CPU 利用率

  • 具有自适应调节策略

5. Prarllel Old 收集器

  Prarllel Scavenge 收集器的老年代版本,使用多线程标记整理算法。如果系统对吞吐量要求较高,可以采用 Prarllel Scavenge 与 Prarllel Old 搭配策略。

  • 多线程收集器

  • 使用标记整理算法

  • 注重提高系统吞吐量

6. CMS 收集器

  CMS 收集器是一种老年代收集器,主要目标是获得最短垃圾回收停顿时间,以获得较高的响应比,提高用户体验。使用多线程的标记清除算法。

  • 多线程收集器

  • 使用标记清除算法

  • 注重缩短垃圾收集停顿时间,追求高响应比

工作机制如下:

  • 初始标记:只标记 GC Roots 能直接关联的对象,速度快,需要暂停所有线程

  • 并发标记:进行 GC Roots 追踪,和用户线程一起工作,不需要暂停

  • 重新标记:修正在并发标记期间,用户线程运行而导致标记改变的对象,需要暂停所有线程

  • 并发清除:清除 GC Roots 不可达对象,和用户线程一起工作,不需要暂停

  由于耗时最长的并发标记和并发清除不需要暂停其他线程,CMS 可近似看做与用户线程并发执行。

7. G1 收集器

  Garbage First 垃圾收集器是目前垃圾收集器理论最前沿的成果。

  G1 避免全区域垃圾收集,把堆内存划分为大小固定的几个独立区域,并跟踪这些区域的垃圾收集进度,在后台维护一个优先级列表,每次根据允许收集时间来优先回收垃圾最多的区域。

相较于 CMS,G1 有如下优势:

  • 基于标记整理算法,不产生内存碎片

  • 可精确控制停顿时间,在不牺牲吞吐量的前提下实现低停顿回收

8. 总结

收集器 运行模式 工作范围 算法 目标 适用场景
Serial 串行 新生代 复制算法 响应速度优先 单CPU环境下的Client模式
Serial Old 串行 老年代 标记整理 响应速度优先 单CPU环境下的Client模式、CMS的后备预案
ParNew 并行 新生代 复制算法 响应速度优先 多CPU环境时在Server模式下与CMS配合
Parallel Scavenge 并行 新生代 复制算法 吞吐量优先 在后台运算而不需要太多交互的任务
Parallel Old 并行 老年代 标记整理 吞吐量优先 在后台运算而不需要太多交互的任务
CMS 并发 老年代 标记清除 响应速度优先 集中在互联网站或B/S系统服务端上的Java应用
G1 并发 Both 复制+标记整理 响应速度优先 面向服务端应用,将来替换CMS