Shenandoah GC算法

概述

最早由Red Hat公司发起,目标是利用现代多核CPU的优势,减少大堆内存在GC时产生的停顿时间。随OpenJDK 12一起发布,暂停时间不依赖于堆的大小;这意味着无论堆的大小如何,暂停时间都是差不多的。

Shenandoah最初的目标是把GC停顿时间降到毫秒级,并且将对内存的支持扩展到太字节级别。为降低停顿时间,回收器需要使用更多的线程来并发处理回收任务,而要在降低停顿时间的同时能够支持更大的堆空间,回收器对CPU的多核处理能力提出更高的要求。

支持的特性:

  • 解释器
  • C1屏障
  • C2屏障
  • 引用
  • JNI临界区域
  • System.gc()

策略

Shenandoah GC策略

策略GC触发的条件GC选择回收分区的条件
static当内存可用达到一定的國值之后,将启动GC在进行GC时,只选择垃圾超过一定阈值的分区
passive直到发生OOM,直接启动FGC在进行GC时,只选择垃圾超过一定阈值的分区,并且分区在转移后仍然能保留一定的预留空间
aggressive总是启动GC在进行GC时,只要分区有垃圾就会启动GC。判断分区是否有垃圾的条件:分区中垃圾超过一定的阈值;分区中可用的对象所占的空间小于一定的阈值
adaptive默认选项。当内存可用达到一定的阈值之后,或从上次GC到现在已经使用的内存超过一定阈值后,或根据使用的内存预测可用的内存不足以支撑到下一次GC时,将启动GC在进行GC时,只选择垃圾超过一定阈值的分区,并且分区在转移后仍然能保留一定的预留空间
compact当内存可用达到一定的阈值之后,或从上次GC到现在已经使用的内存超过一定阈值后,将启动GC在进行GC时,只选择垃圾超过一定阈值的分区,并且分区在转移后仍然能保留一定的预留空间。与自适应策略相比,它的阈值更低,回收的分区更多。
traversal启动遍历GC,是正常GC的优化版,把重定向和标记进行合并。GC触发时机和adaptive策略相同回收的分区策略也和adaptive策略相同

GC策略决定Shenandoah何时启动GC以及在GC时回收哪些分区。

算法

Shenandoah为了更好地管理内存,实现4类GC算法:

  1. 正常回收算法(Normal GC):GC的过程通常按照初始标记、并发标记、再标记、并发转移、结束转移的步骤执行
  2. 降级回收算法(Degenerated GC):在GC过程中,如果遇到内存分配失败,将进入降级回收。降级回收实质上是在STW中进行的并行回收
  3. 全回收算法(Full GC):如果在降级回收中再次遇到内存分配失败的情况,将进入全回收。和G1的并行FGC非常类似。
  4. 遍历回收算法(Traversal GC):GC过程按照初始遍历、并发遍历、预清理和结束遍历的步骤执行。

降级回收算法和并行FGC类似,都是在STW中进行的。它和FGC最大的区别就是降级回收会重用当前已经并发执行的标记、转移或者重定位的信息,从当前GC失败的地方继续向下执行。

正常回收

Shenandoah中正常回收有两种模式:一般模式和优化模式。区别在于是否在标记时执行重定位,在标记的过程中执行重定位,则称为优化模式,否则称为一般模式。可通过参数ShenandoahUpdateRefsEarly控制,可能值为off/false,表示GC执行优化模式;on/true/adaptive,表示执行一般模式。

一般模式GC步骤:

  • 初始标记:Init Mark,从根集合出发,标记根集合所有引用的对象,这些对象作为第二步并发标记的出发点。会触发STW
  • 并发标记:Concurrent Marking,以第一步标记的对象作为出发点,开始并发地标记对象
  • 预清理:在进入再标记阶段之前,先处理引用对象,把仍然活跃的引用对象重新激活,不进行真正的GC。在该阶段是并发执行的,但是只有一个并发工作线程执行预清理
  • 再标记:在该阶段要做3件事:终止标记、计算回收集、转移根集合直接的引用对象。会触发STW
  • 清理:再标记结束后,部分分区可能已经没有任何活跃对象,这些分区就可以被回收
  • 并发转移:Concurrent Evacuation,根据转移集,对所有在转移集中的活跃对象进行转移
  • 初始重定位:Init Update Refs,初始重定位将根据SATB算法重置分区中对象分配的起始内存地址位置。会触发STW
  • 并发重定位:遍历不属于回收集合中的分区的对象,根据brook pointer更新对象的引用指针
  • 结束重定位:遍历根集合中所有引用的对象,更新对象的引用指针。会触发STW
  • 再清理:因回收集合中对象全部转移完成,所以可以释放空间。

整个GC活动图:
在这里插入图片描述
优化模式GC的步骤:

  • 初始标记:和一般模式中初始标记相同
  • 并发标记:以第一步标记的对象作为出发点,开始并发地标记对象,注意在这一步中首先判断对象是否需要重定位,如果需要,则进行重定位
  • 预清理:和一般模式中预清理相同
  • 再标记:在该阶段主要做4件事,分别为更新根集合中所有对象的引用、终止标记、计算回收集、转移根集合直接的引用对象。在STW中进行
  • 清理:和一般模式中清理相同
  • 并发转移:和一般模式中并发转移相同
  • 结束转移:设置转移结束标记,重置TLAB等信息。在STW中进行

Shenandoah中的优化模式和ZGC的GC过程基本类似,把标记阶段和重定位阶段合并。正常回收在运行的过程中,应用程序和GC线程都可能需要分配内存空间,也都有可能遇到内存不足导致分配失败的情况,此时正常回收将进入降级回收状态,如果在降级回收时再遇到内存不足,将进入FGC状态。

正常回收、降级回收和FGC交互图:
在这里插入图片描述

遍历回收

Shenandoah遍历回收就是把并发标记、并发转移和并发重定位合并到一个阶段。

Shenandoah遍历回收的步骤:

  • 初始遍历:初始遍历待回收集合,从根集合出发,标记根集合所用引用的对象,这些对象作为第二步并发标记的出发点。会触发STW
  • 并发遍历:根据第一步标记的对象作为出发点,开始并发地标记对象
  • 结束遍历:该阶段主要做两件事,分别为标记SATB队列中新增的引用对象、终止标记。会触发STW
  • 清理:清理可回收的分区

遍历回收算法,思路简单但实现复杂。需要解决两个问题:

  1. 如何选择带回收的分区?在进入优化回收时,第一次GC还没有足够的信息表明分区对象的存活情况,所以需要在下一次GC时才能选择哪些分区能够被回收。
  2. 如何保持一致性?主要有3种一致性问题:遍历一致性、数据一致性和重定位一致性。
    • 遍历一致性:如何在遍历时正确地处理对象关系图的变化?
    • 数据一致性:如何保证读的时候总是访问最新的数据?如何保证写的时候能访问到正确的对象?
    • 重定位一致性:如何避免一般的成员变量更新和重定位成员变量更新的竞争?

Shenandoah中解决一致性问题的方法到也比较简单。通过执行顺序的不同来保证一致性。具体来说在标记时,如果对象需要更新引用,则先更新引用,如果没有引用更新,则判断是否需要转移,如果需要转移则转移,最后才能标记对象。

延伸

对比G1、ZGC

G1、ZGC和Shenandoah的异同点

对比项G1ZGCShenandoah GC
内存连续性堆内存基于分区实现,最小分区为1MB,最大分区可达32MB基于分页设计,类似于G1分区。页面有3种类型,2MB、32MB和N*MB基于分区理论实现,最小分区为256KB,最大分区可为32MB
是否支持分代支持不支持不支持
是否全量回收新生代分区在 YGC/MixedGC/FGC 中会被全部回收老生代在 Mixed GC 时部分回收,在 FGC 时全部回收部分页面回收部分分区回收
屏障支持读屏障和写屏障,读屏障是为了正确标记对象,写屏障是为了处理代际引用关系管理(G1中有单独的线程处理代际引用)仅需要支持读屏障即可实现并发标记、并发转移和并发重定位支持读屏障和写屏障,读屏障是为了对象正确标记和并发处理读数据写屏障是为了并发处理同时写数据、实际上Shenandoah还需要支持比较屏障(比较屏障是通过两个读屏障实现的)
GC时并发性目前只支持并发标记支持并发标记、并发转移和并发重定位支持并发标记、并发转移和并发重定位
GC触发策略使用衰减停顿模型预测是否启动GC提供多种触发GC的规则,其中最为常见的触发方式是根据正态分布预测的内存分配的情况触发提供多种触发GC的策略:static、passive、aggressive、compactadaptive
NUMA支持尚未支持,提案JEP 345为G1支持NUMA支持不支持
字符串去重支持不支持支持
引用处理并行处理并发处理并行处理

在GC时非常类似,都实现并发垃圾标记、并发转移、并发重定位、压缩堆空间。Shenandoah更加类似于G1,把G1中的并行转移变成并发转移。

ZGC并发的基础是地址多视图映射。

Shenandoah并发的基础是在对象头增加一个额外数据Brook pointer,在实现读写屏障时通过Brook pointer访问对象。

参考

  • 新一代垃圾回收器ZGC设计与实现

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/536604.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[C++][算法基础]图中点的层次(树图BFS)

给定一个 n 个点 m 条边的有向图,图中可能存在重边和自环。 所有边的长度都是 1,点的编号为 1∼n。 请你求出 1 号点到 n 号点的最短距离,如果从 1 号点无法走到 n 号点,输出 −1。 输入格式 第一行包含两个整数 n 和 m。 接…

【MCU开发规范】:MCU的性能测试

MCU的性能测试 前序性能评判方法MIPSCoreMark EEMBC其他参考 前序 我们平时做MCU开发时,前期硬件选型(选那颗MCU)基本由硬件工程师和架构决定,到软件开发时只是被动的开发一些具体功能,因此很少参与MCU的选型。 大部分…

Ant Desgin Vue Tree Tab 个性化需求

背景 个人对前端不是很熟,或者说过目就忘,但是对前端还要求不少,这就难搞了。 使用的前端是Mudblazor和ant design vue, Mudblazor 还没有开始搞,现在先用ant design vue,版本是vue3, ant design vue 4版…

4.11学习总结

一.IO流 一.java中IO的初步了解 (一).概念: Java中I/O操作主要是指使用Java进行输入,输出操作. Java所有的I/O机制都是基于数据流进行输入输出,这些数据流表示了字符或者字节数据的流动序列。Java的I/O流提供了读写数据的标准方法。任何Java中表示数据…

Excel·VBA二维数组S形排列

与之前的文章《ExcelVBA螺旋数组函数》将一维数组转为二维螺旋数组 本文将数组转为S形排列的二维数组,类似考场座位S形顺序 Function S形排列(ByVal arr, ByVal num_rows&, ByVal num_cols&, Optional ByVal mode$ "row")将数组arr转为num_rows…

必须掌握的这4种缓存模式

概述 在系统架构中,缓存可谓提供系统性能的简单方法之一,稍微有点开发经验的同学必然会与缓存打过交道,起码也实践过。 如果使用得当,缓存可以减少响应时间、减少数据库负载以及节省成本。但如果缓存使用不当,则可能…

有趣的css - 动态雷达扫描

大家好,我是 Just,这里是「设计师工作日常」,今天分享的是使用 css 实现一个动态的雷达扫描,快学起来吧! 《有趣的css》系列最新实例通过公众号「设计师工作日常」发布。 目录 整体效果核心代码html 代码css 部分代码…

当然IP总流量卵化手14无线天线上实际操作夏令营【第9期】月入5w 上百万爆款打造 (74节)

在2023年,我依照导师的”项目销售”策略,成功地实现了超过100万的纯利润。在当前经济低迷的大环境下,许多大型企业纷纷裁员,这使得许多人面临着找不到满意工作的困境。与此同时,由于疫情引发的口罩需求,使得…

算法刷题Day31 | 455.分发饼干、376. 摆动序列、53. 最大子数组和

目录 0 引言1 分发饼干1.1 我的解题1.2 更好的解题 2 摆动序列2.1 我的解题2.2 我的错误原因(GPT分析)2.3 改进 3 最大子数组和3.1 我的解题 🙋‍♂️ 作者:海码007📜 专栏:算法专栏💥 标题&…

爬虫实战:我国城市的地铁数据以及分析

文章目录 1 引言2 项目背景3 技术栈和工具选择4 数据爬取4.1 爬虫设计4.2 代码实现4.3 数据保存4.4 关键点分析 5 数据处理与分析5.1 数据清洗5.2 数据分析5.3 关键点分析 6 完整代码以及结果展示7 小分享 1 引言 本文将指导你如何通过Python从高德地图爬取中国城市地铁站数据…

5G-A有何能耐?5G-A三载波聚合技术介绍

2024年被称作5G-A元年。5G-A作为5G下一阶段的演进技术,到底有何能耐呢? 三载波聚合(3CC)被认为是首个大规模商用的5G-A技术,将带来手机网速的大幅提升。 █ 什么是3CC 3CC,全称叫3 Component Carriers…

前端js基础知识(八股文大全)

一、js的数据类型 值类型(基本类型):数字(Number)、字符串(String)、布尔(Boolean)、对空(Null)、未定义(Undefined)、Symbol,大数值类型(BigInt) 引用数据类型:对象(Object)、数组…

HNUST湖南科技大学嵌入式开发板使用-2024

目录 1.需要准备的软件(版本必须相同)꒰ঌ( ⌯ ⌯)໒꒱ 2.下载链接地址⌯▾⌯ 3.软件安装教程 4.安装好了,正常情况会是什么样子呢?(๑•̌.•๑) 4.1.拆入第一个接口(串口com接口是用来上传代码的ฅ˙Ⱉ˙ฅ) 4.2.拆入第三个接口(SWD Jlink口…

android android.permission.MANAGE_EXTERNAL_STORAGE使用

android11 及以上版本&#xff0c;如果release版本要读取外部存储公共目录&#xff0c;即sdcard公共目录&#xff0c;需要在androidManifest.xml下申明 <uses-permission android:name"android.permission.MANAGE_EXTERNAL_STORAGE" /> 如果要发版到海外&…

数据资产与数据要素的重要性及数据资产入表的实践指南

## 引言在当今快速发展的数字化时代&#xff0c;数据资产已经成为企业最宝贵的资源之一。数据资产不仅对企业的运营决策有着至关重要的影响&#xff0c;而且在企业的财务健康和市场竞争力方面扮演着核心角色。数据要素&#xff0c;作为构成数据资产的基本单元&#xff0c;其管理…

Centos Docker Oracle11g 密码过期修改

症状&#xff1a; Centos Oracle11g环境变量配置 如果没有配置环境变量&#xff0c;需要先配置Oracle环境变量&#xff0c;否则执行sqlplus时会提示&#xff1a;SP2-0750: You may need to set ORACLE_HOME to your Oracle software directory 配置方法&#xff1a; 第一步&a…

C++ 2024-4-2 作业

1.模板类实现顺序栈 #include <iostream> #define MAX 8 using namespace std; template<typename T> class stack {T data[MAX];int top; public:stack():top(-1){}bool empty_stack();bool full_stack();void push_stack(T data);void pop_stack();void show();…

定长子串中元音的最大数目

题目链接 定长子串中元音的最大数目 题目描述 注意点 s 由小写英文字母组成返回字符串 s 中长度为 k 的单个子字符串中可能包含的最大元音字母数1 < k < s.length 解答思路 根据滑动窗口的思想&#xff0c;维持一个大小为k的窗口&#xff0c;每次移动窗口时整体向右…

【ROS2笔记三】构建ROS2功能包

3.构建ROS2功能包 文章目录 3.构建ROS2功能包3.1ROS2中包的组成部分3.2创建ROS2功能包并编写节点3.2.1使用CMake创建功能包3.2.2编写cpp节点代码 3.3编译运行节点3.4使用面向对象的方式编写ROS2节点3.5使用RCLPY编写节点Reference 3.1ROS2中包的组成部分 ROS2可以使用CMake或者…

用于显著提高检索速度和降低成本的二进制和标量嵌入量化

我们引入了嵌入量化的概念&#xff0c;并展示了它们对检索速度、内存使用、磁盘空间和成本的影响。我们将讨论理论上和实践中如何对嵌入进行量化&#xff0c;然后介绍一个 演示&#xff0c;展示了 4100 万维基百科文本的真实检索场景。 演示地址https://hf.co/spaces/sentence-…