带你走近Java虚拟机到底有哪些经典的垃圾收集器

上一篇文章中我们大致讲了一下Java虚拟机的垃圾收集算法,如果说垃圾收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的实践者。

经典的垃圾收集器

话不多说先上一张各款经典垃圾收集器之间的关系图:带你走近Java虚拟机到底有哪些经典的垃圾收集器接下来我们一个个进行了解:

Serial 收集器-新生代

Serial收集器是最基础、历史最悠久的垃圾收集器。

主要特点:
  • 它在进行垃圾收集的过程中,必须暂停所有其它工作线程,直到它收集结束。Stop The World 在这里体现的也是淋漓尽致。
  • 比较适合单核处理器或者多核核心数较少的环境下,对比同类收集器而言简单高效;同时是所有垃圾收集器中额外内存消耗最小的
  • 采用的是标记-复制算法 。
垃圾收集过程:
带你走近Java虚拟机到底有哪些经典的垃圾收集器
image.png

ParNew 收集器-新生代

简单来说它本质上就是Serial收集器的多线程并行版本。

主要特点:
  • 目前除了Serial、只有它能与CMS收集器配合工作
  • 采用的是标记-复制算法 。
垃圾收集过程
带你走近Java虚拟机到底有哪些经典的垃圾收集器
image.png

Parallel Scavenge收集器-新生代

该收集器很多特性和ParNew都类似。但是与其它收集器不同的是它关注的点不一样,Parallel Scavenge收集器关注的是能否达到一个可控制的吞吐量,而CMS等收集器关注的是垃圾收集过程中用户线程暂停的时间。

  • 吞吐量:处理器用于运行用户代码的时间与处理器总消耗时间的比值
带你走近Java虚拟机到底有哪些经典的垃圾收集器
image.png
主要特点
  • 主要是用场景是适合在后台运算而不需要太多交互的分析任务,由于该收集器关注吞吐量所以又被称为吞吐量优先收集器
  • 采用的是标记-复制算法 。
精确控制吞吐量的参数
  • -XX:MaxGCPauseMillis   控制最大垃圾收集停顿时间
  • -XX:GCTimeRatio  设置吞吐量的大小

Serial Old收集器 – 老年代

Serial收集器的老年代版本 主要有两点作用:

  1. JDK5之前与Parallel Scavenge收集器搭配使用
  2. 作为CMS收集器发生失败时的后备预案
主要特点
  • 单线程收集器
  • 采用的是标记-整理算法 。
垃圾收集过程
带你走近Java虚拟机到底有哪些经典的垃圾收集器
image.png

Parallel Old收集器 – 老年代

支持多线程并发收集,JDK6之后才提供。它是Parallel Scavenge的老年代版本

主要特点
  • 采用的是标记-整理算法
垃圾收集过程
带你走近Java虚拟机到底有哪些经典的垃圾收集器
image.png

CMS收集器- 老年代

也被称为并发低停顿收集器JDK 5 发布时,HotSpot 推出了一款在强交互应用中几乎可称为具有划时代意义 的垃圾收集器——CMS 收集器;首次实现了让垃圾收集线程与用户线程(基本上)同时工作

主要特点:
  • 采用的是标记-清除算法
  • 以获取最短回收停顿时间为目标的垃圾收集器,适用于更加关注服务的响应速度的应用需求
垃圾收集过程
带你走近Java虚拟机到底有哪些经典的垃圾收集器
image.png
  • 初始标记:这里仍需要Stop The World
  • 并发标记:可以与用户线程一起工作
  • 重新标记:这里仍需要Stop The World
  • 并发清理:可以与用户线程一起工作
缺点

所谓的缺点自然也离不开它依赖的算法所带来的弊端

  • 在并发阶段,虽然不会导致用户线程停顿,但却会因为占用了一部分线程(或者说处理器计算的能力),从而导致应用程序变慢,降低吞吐量。CMS默认启动的回收线程数(处理器核心数量+3)/4
    • 有过缓解方案:增量式并发收集器-JDK9后被废弃
  • 无法处理浮动垃圾

所谓的浮动垃圾就是CMS 的并发标记和并发清理阶段,用户线程是还在继续运行的,程序在运行自然就还会伴随有新的垃圾对象不断产生,但这一部分垃圾对象是出现在标记过程结束以后,CMS 无法在当次收集中处理掉它们,只好留待下一次垃圾收集时再清理掉。这一部分垃圾就称为“浮动垃圾” 可以通过禅师-XX:CMSInitiatingOccu-pancyFraction去进行提高CMS触发的百分比 设置得太高将会很容易导致大量的并发失败产生,性能反而降低,用户应在生产环境中根据实际应用情况来权衡设置。

  • 由于采用的是标记-清除算法,自然也就会有空间碎片化的存在;

可以通过-XX:+UseCMS-CompactAtFullCollection -XX:CMSFullGCsBeforeCompaction参数来配置,但是在JDK9也被废弃了

  • -XX:+UseCMS-CompactAtFullCollection :用于在 CMS 收集器不得不进行 Full GC 时开启内存碎片的合并整理过程
  • -XX:CMSFullGCsBeforeCompaction:要求 CMS 收集器在执行过若干次(数量由参数值决定)不整理空间的 Full GC 之 后,下一次进入 Full GC 前会先进行碎片整理(默认值为 0,表示每次进入 Full GC 时都 进行碎片整理)。

Garbage First 收集器

Garbage First(简称 G1)收集器是垃圾收集器技术发展历史上的里程碑式的成果, 它开创了收集器面向局部收集的设计思路和基于 Region 的内存布局形式。JDK 8 Update 40后 G1 收集器才被 Oracle 官方称为“全功能的垃圾收集器”(Fully-Featured Garbage Collector)。G1 是一款主要面向服务端应用的垃圾收集器JDK9之后G1 宣告取代 Parallel Scavenge 加 Parallel Old 组合, 成为服务端模式下的默认垃圾收集器,而 CMS 则沦落至被声明为不推荐使用 (Deprecate)的收集器 Region分区示意图:带你走近Java虚拟机到底有哪些经典的垃圾收集器

垃圾收集过程
带你走近Java虚拟机到底有哪些经典的垃圾收集器
image.png
  • 初始标记
  • 并发标记:出了该阶段外其它阶段也是要暂停用户线程的
  • 最终标记
  • 筛选回收
主要特点:
  • 从G1回收器开始,最先进的垃圾收集器的设计导向都不约而同的变为追求能够应付应用的内存分配速率,而不是追求一次将Java堆全部清理干净。
  • 关于算法方面:整体上是采用的标记-整理算法,但是如果要是从局部(两个region)之间采用的标记-复制算法。所以这也意味着G1垃圾收集器在运行期间不会产生内存空间碎边化的问题。
  • 同时用户线程运行过程中,G1无论是为了垃圾收集产生的内存占用还是程序运行时的额外执行负载都要比CMS要高。
  • G1的卡表设计更为复杂,相比CMS的卡表就是比较简单,只有唯一一份,而且只需要处理老年代到新生代的引用
  • G1由于其特性目前是在大内存应用上能够发挥其优势
  • CMS和G1分别使用增量更新和原始快照技术

TIP:

衡量垃圾收集器的三项重要指标是:内存占用``吞吐量``延迟

低延迟的垃圾收集器

Shenandoah收集器

主要特点:
  • Shenandoah收集器摒弃了在G1中耗费大量内存和计算资源去维护的记忆集,改用名为连接矩阵的全局数据结构来记录跨Region的引用关系,降低了处理跨代指针时的记忆集维护消耗,也降低了伪共享问题发生的概率
  • 连接矩阵

连接矩阵可以简单的理解为一张二维表格,如果Region N有对象指向Region M,就在表哥的N行M列打上一个标记。

  • 整个工作过程全部都是并发的,只有初始标记、最终标记这些阶段有短暂的停顿,这部分停顿的时间基本上是固定的,与堆的容量、堆中对象的数量没有正比例关系
  • ZGC 和 Shenandoah 的目标是高度相似的,都希望在尽可能对吞吐量影响不太大的 前提下,实现在任意堆内存大小下都可以把垃圾收集的停顿时间限制在十毫秒以内的低延迟
垃圾收集过程
带你走近Java虚拟机到底有哪些经典的垃圾收集器
image.png
  • 初始标记
  • 并发标记(重点理解)
  • 最终标记
  • 并发清理
  • 并发回收(重点理解)
  • 初始引用更新
  • 并发引用更新(重点理解)
  • 最终引用更新
  • 并发清理

ZGC(Z Garbage Collector)收集器

主要特点:

  • 内存布局与Shenandoah、G1一样采用的Region堆内存布局;不同的是ZGC的Region有些官方资料称为page或ZPage,它们动态性(动态创建和销毁以及动态区域容量大小);ZGC的Region有三种大、中、小容量。
    • 大型Region:容量不固定,可以动态变化,但是必须是2MB的整数倍,由于放置4MB或以上的大对象。每个大型Region中只存放一个大对象,但是实际容量可能会小于中型Region,并且最小容量可以低至4MB,大型Region在ZGC的实现中是不会被重分配的
    • 中型Region(Medium Region):容量固定为32MB,用于放置大于等于256KB但小于4MB的对象。
    • 小型Region(Small Region):容量固定为2MB,用于放置小雨256KB的小对象。
  • ZGC收集器有一个标志性的设计它采用的是染色指针技术(Colored Pointer)

染色指针是一种直接将少量额外的信息存储在指针上的技术

垃圾收集过程

带你走近Java虚拟机到底有哪些经典的垃圾收集器
image.png
  • 并发标记:遍历对象图做可达性分析的阶段,与G1、Shenandoah不同的是ZGC的标记是在指针上而不是在对象上,标记阶段会更新染色指针中的Marked0、Marked1标志位
  • 并发预备重分配:需要根据特定的查询条件统计出本次收集过程要清理哪些Region,将这些Region组成重分配集(Relocation Set)。重分配集和G1的回收集是不一样的。
  • 并发重分配:这个阶段是要把重分配集中的存活对象复制到新的Region上,并为重分配集的每个Region维护一个转发表(Forward Table)。
  • 并发重映射:主要是做修正整个堆中指向重分配集中旧对象的所有引用,这一点从目标上看是与Shenandoah并发引用更新阶段一样的。


原文始发于微信公众号(码上遇见你):带你走近Java虚拟机到底有哪些经典的垃圾收集器

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/78564.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!