分代ZGC详解

ZGC(Z Garbage Collector)是Java平台上的一种垃圾收集器,它是由Oracle开发的,旨在解决大堆的低延迟垃圾收集问题。ZGC是一种并发的分代垃圾收集器,它主要针对具有大内存需求和低停顿时间要求的应用程序

分代ZGC收集器具备以下特性:

  • 没有多重映射内存
  • 内存屏障优化
  • 双重缓冲记忆集
  • 无需额外堆内存重分配
  • 堆区域密度
  • 大对象处理

核心概念

染色指针

染色指针是指向堆中对象的指针,该对象与对象的内存地址一起包含对对象的已知状态进行编码的元数据。元数据描述了对象是否已知是活动的、地址是否正确等等。

分代ZGC染色指针布局

在分代 ZGC 中,存储在对象字段中的对象引用被实现为染色指针。然而,存储在 JVM 堆栈中的对象引用在硬件堆栈或 CPU 寄存器中实现为无色指针,没有元数据位。读屏障和存储屏障控制染色指针和无色指针之间的转换。

由于染色指针永远不会出现在硬件堆栈或 CPU 寄存器中,因此只要可以有效地完成染色指针和无色指针之间的转换,就可以使用更奇特的染色指针布局

Generational ZGC 使用的染色指针布局将元数据放在指针的低位中,将对象地址放在高位中,这最大限度地减少了负载屏障中的机器指令数量。通过仔细编码内存地址和元数据位,单个移位指令(在 x64上)既可以检查指针是否需要处理,也可以删除元数据位。

GC 阶段标记

非分代 ZGC 判断指针处于哪一个GC阶段很简单,只需要简单的位移:

movq  rax, 0x10(rbx)
testq rax, 0x20(r15)
jnz   slow_path

testq即等价于&操作,是一般的 bitflag 做法

分代 ZGC 的代码是这样的:

movq rax, 0x10(rbx)
shrq rax, $address_shift
ja   slow_path

shrq 是右移操作,同时会设置 Carry Flag 为最后移除的一位,同时如果右移的结果为 0,Zero Flag 也会被设为 0。

ja是 jump if above 指令,仅在CF == 0 && ZF == 0时跳转

该指令的操作过程可以见下图

分代 ZGC 加载屏障示意图

每次加载均会将地址右移,同时由于 8 字节对齐,JVM 保证了最低三位的值一定为 0,因此若该指针被更新(最后被移除的位值为 1),则会跳入 slow path 分支处理下一个 GC 阶段

最大堆大小

对于64位系统,ZGC支持最大堆大小:JDK11(4TB) -> JDK15(16TB) -> JDK21(16TB+)

JDK 15 ZGC对象指针

在64位的Linux操作系统中,高18位(或称为高16TB)是由内核保留的,在用户空间是无法直接寻址的。JDK15中使用了其中两位作为标志位

HotSpot虚拟机的标记实现方案

  • Serial: 标记记录在对象头上
  • G1/Shenandoah: 标记记录在与对象相互独立的数据结构(BitMap)上
  • ZGC: 标记信息记在引用对象的指针上

多重映射内存

分代ZGC不再使用多重映射内存

内存多重映射(Multi-Mapping)将多个不同的虚拟内存地址映射到同一个物理内存地址上,是一种多对一映射

内存屏障

由于分代 ZGC 的元数据比较多,使用多重映射内存的方法不再能行得通。因此,在寄存器和栈中的内存地址需要为普通的无色指针。分代 ZGC 不再能通过此减少加载或存储内存屏障的开销,需要在有色和无色指针之间转换,即:

  • 加载屏障: 在加载时移除元数据
  • 存储屏障: 在存储时恢复元数据

用于优化屏障的一些技术是:

  • 快路径和慢路径
  • 最小化加载屏障职责
  • 记忆集屏障
  • SATB 标记屏障
  • 混合存储屏障检查
  • 存储屏障缓冲区
  • 屏障修补

快路径和慢路径

快路径检测是否需要额外的 GC 工作,当需要时,会跳转进入慢路径,开始相关工作。快路径由 JIT 实现,会直接插入 GC 代码至 JIT 编译后的程序。而慢路径不经常调用,所以使用 C++ 实现

最小化加载屏障职责

分代 ZGC 中,我们需要监控年轻代和老年代,并且在有色指针和无色指针间转换。为了简化加载屏障的复杂性,并引入优化加载屏障的空间,标记的职责交给了加载屏障

在分代 ZGC 中,加载屏障负责:

  • 转换有色指针为无色指针
  • 更新已被 GC 更新的过时指针

存储屏障负责:

  • 转换无色指针为有色指针
  • 维护记忆集
  • 标记对象存活

记忆集和 SATB

记忆集和SATB的概念与G1中一致,详细可见G1 垃圾收集器详解

存储屏障缓冲区

将障碍分为快速路径和慢速路径,并使用指针着色,可以减少对 C++ 慢速路径函数的调用次数。

分代 ZGC 通过在快速路径和慢速路径之间放置 JIT 编译的中间路径来进一步减少开销。中间路径将要覆盖的值和对象字段的地址存储在存储屏障缓冲区中,并返回到已编译的应用程序代码,而不需要采取昂贵的慢速路径。仅当存储屏障缓冲区已满时才采用慢速路径。这可以分摊从编译的应用程序代码转换到 C++ 慢路径代码的一些开销

双重缓冲记忆集

ZGC 的记忆集不使用卡表实现,而是由两个 bitmap 实现。一个 bitmap 用于用户线程,在加载屏障中修改,另一个只读的 bitmap 用于 GC。这样做有两个好处:

  • 用户线程无需等待 bitmap 被清除
  • 因为分了两个 bitmap,所以不需要额外的内存屏障,造成额外的内存开销

无需多余堆空间的重分配

其他 HotSpot GC 中的年轻代回收使用清理模型,GC 一次性找到存活对象并重分配。在 GC 完全了解哪些对象还活着之前,年轻代中的所有对象都必须重分配,在这之后才能回收内存。因此,这些 GC 需要猜测存活对象所需的内存量,并确保在 GC 启动时该内存量可用。如果猜错了,则需要更昂贵的清理操作:例如,就地固定未重分配的对象,这会导致内存碎片,或者 Full GC。

分代 ZGC 有两个阶段:

  1. 访问并标记所有可达对象
  2. 重分配标记的对象

由于 GC 在重分配之前就知道对象是否存活,因此可以按区域粒度划分工作。一旦存活对象都被重分配出某个区域,即该区域已被清除,该区域就被当作新的目标区域,继续用于重分配或被应用使用。即使没有额外的堆空间,ZGC 仍可通过将压缩对象到当前区域来继续重分配。这使得分代 ZGC 能够重分配并压缩年轻代,而无需使用额外的堆内存

堆区域密度

如果一个区域的存活对象很多,将它们一个个移到老年代堆的操作是不值得的。ZGC 会分析年轻代存活对象的密度,以此为一句来判断是否有机会就地升级为老年代。否则,这个区域会保留为年轻代

大对象处理

ZGC 已经可以很好地处理大型对象。通过将虚拟内存与物理内存解耦,并提前保留虚拟内存,大对象的碎片问题通常可以避免

在分代 ZGC 中,允许在年轻代中分配大对象。鉴于该区域现在可以在不重分配的情况下老化,因此不再需要在老一代中分配大对象。相反,如果大对象寿命较短,则可以在年轻代中收集它们;如果寿命较长,则可以廉价地将它们提升到老年代。

ZGC JVM参数

ZGC 通用参数

参数描述默认值
-XX:MinHeapSize, -Xms最小堆大小8M
-XX:InitialHeapSize, -Xms初始化堆大小128M
-XX:MaxHeapSize, -Xmx最大堆大小2036M
-XX:SoftMaxHeapSizeJVM堆的最大软限制2036M
-XX:ConcGCThreads并发GC的线程数量1
-XX:ParallelGCThreads设置垃圾回收时的并行GC线程数量4
-XX:UseLargePages使用大页面内存false
-XX:UseTransparentHugePages使用Transparent大页面内存
-XX:UseNUMA使用UNMA内存分配,可以获得更好的性能
-XX:SoftRefLRUPolicyMSPerMB每MB的空闲内存空间允许软引用对象存活时间1000
-XX:AllocateHeapAt堆分配参数,可以使用非DRAM 内存

ZGC 特有参数

参数描述默认值
-XX:ZAllocationSpikeTolerance修正系数,数值越大,越早触发GC2.000000
-XX:ZCollectionIntervalZGC发生的最小时间间隔,单位秒0.000000
-XX:ZFragmentationLimitrelocation时,当前region碎片化大于此值,则回收region25.000000
-XX:ZMarkStackSpaceLimit指定为标记堆栈分配的最大字节数8096M
-XX:ZProactive是否启用主动回收true
-XX:ZUncommit是否归还不使用的内存给OStrue
-XX:ZUncommitDelay不再使用的内存最多延迟多久会归还给OS300s

ZGC 诊断选项

通过-XX:+UnlockDiagnosticVMOptions开启诊断选项

参数描述
-XX:+UnlockDiagnosticVMOptions使用诊断模式,下面的参数才会起作用
-XX:ZStatisticsInterval指定统计数据输出之间的时间间隔(秒)
-XX:ZVerifyForwarding检验转发表
-XX:ZVerifyMarking检验标记集
-XX:ZVerifyObjects检验对象
-XX:ZVerifyRoots检验根节点
-XX:ZVerifyViews检验堆视图访问

分代ZGC 特有参数

参数描述
-XX:ZCollectionIntervalMinorZGC进行年轻代垃圾收集(MinorGC)的时间间隔(秒)
-XX:ZCollectionIntervalMajorZGC进行老年代垃圾收集(MajorGC)的时间间隔(秒)
-XX:ZYoungCompactionLimit控制ZGC何时进行年轻代的压缩操作

参考资料:

  1. 深入理解Java虚拟机第三版
  2. JEP 439: Generational ZGC
  3. JEP 377: ZGC: A Scalable Low-Latency Garbage Collector (Production)
  4. 理解并应用JVM垃圾收集器-ZGC
  5. 分代ZGC
  6. G1 垃圾收集器详解
  7. JDK17+ZGC初体验|得物技术

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JVM相关的面试题

一、什么是程序计数器 二、简要的介绍一下堆 三、什么是虚拟机栈 四、能不能解释下方法区 五、你听过直接内存吗? 六、什么是类加载器,类加载器有哪些 七、什么是双亲委派模型 八、JVM为什么采用双亲委派机制 九、类装载的执行过程 十、对象什么时候被垃…

粤嵌实训医疗项目day02(Vue + SpringBoot)

目录 一、创建vue项目并运行 二、vue-cli中的路由使用 三、element-ui框架、实现页面布局以及vue-路由 四、前端登录页面 五、user登录后端接口完善【后端】 六、user登录前端-请求工具-请求发起【前端】 七、请求的跨域-访问策略 八、完善项目的页面布局、导航菜单以及…

Nginx 防盗链

nginx防盗链问题 盗链: 就是a网站有一张照片,b网站引用了a网站的照片 。 防盗链: a网站通过设置禁止b网站引用a网站的照片。 nginx防止网站资源被盗用模块 ngx_http_referer_module 如何区分哪些是不正常的用户? HTTP Referer…

2023年信息科学与工程学院学生科协第一次前端培训

目录 一、前端是什么?前端能做什么?前端需要做什么?现阶段如何理解前端 二、前端学习路线html是什么?css是什么?什么是jshtml、css以及js关系掌握三种语言之后的学习路线 三、HTML基础语法标题段落文本换行文本标签图像…

Calibre拾遗:FDI (Foreign Database Interface)系统简介

Calibre是强大的GDS处理工具,包括查看,验证,分析等操作,操作由浅入深,除过手动编辑GDS的不是很灵活外,其他各种命令和操作策略,都是远(遥)远(遥)走…

视频去噪网络BSVD的实现

前些天写了视频去噪网络BSVD论文的理解,详情请点击这里,这两个星期动手实践了一下,本篇就来记录一下这个模型的实现。 这个网络的独特之处在于,它的训练和推理在实现上有所差别。在训练阶段,其使用了TSM(T…

IP地址SSL证书 IP证书

在许多企业用例中,公司需要SSL证书作为IP地址。公司使用IP地址通过Internet访问各种类型的应用程序。 公网IP地址的SSL证书: 内部IP(也称为私有IP)是IANA设置为保存的IPv4或IPv6地址,例如: RFC 1918范围内…

【JavaEE】CAS -- 多线程篇(7)

CAS 1. 什么是 CAS2. CAS 伪代码3. CAS 是怎么实现的4. CAS的应用4.1 实现原子类4.2 实现自旋锁 5. CAS 的 ABA 问题 1. 什么是 CAS CAS: 全称Compare and swap,字面意思:”比较并交换“能够比较和交换 某个寄存器中的值和内存中的值, 看是否相等, 如果相等, 则把另…

Java面试(JVM篇)——JVM 面试题合集 深入理解JVM虚拟机

关于什么是JVM? 作用: 运⾏并管理Java 源码⽂件所⽣成的Class⽂件,在不同的操作系统上安装不同的JVM ,从⽽实现了跨平台的保证。 ⼀般情况下,对于开发者⽽⾔,即使不熟悉JVM 的运⾏机制并不影响业务代码的…

lvs+keepalived: 高可用集群

lvskeepalived: 高可用集群 keepalived为lvs应运而生的高可用服务。lvs的调度器无法做高可用,于是keepalived软件。实现的是调度器的高可用。 但是:keepalived不是专门为集群服务的,也可以做其他服务器的高可用。 lvs的高可用集群&#xf…

防止消息丢失与消息重复——Kafka可靠性分析及优化实践

系列文章目录 上手第一关,手把手教你安装kafka与可视化工具kafka-eagle Kafka是什么,以及如何使用SpringBoot对接Kafka 架构必备能力——kafka的选型对比及应用场景 Kafka存取原理与实现分析,打破面试难关 防止消息丢失与消息重复——Kafka可…

Hadoop3教程(三十五):(生产调优篇)HDFS小文件优化与MR集群简单压测

文章目录 (168)HDFS小文件优化方法(169)MapReduce集群压测参考文献 (168)HDFS小文件优化方法 小文件的弊端,之前也讲过,一是大量占用NameNode的空间,二是会使得寻址速度…

Redis数据类型——list类型数据的扩展操作

1.list阻塞式数据获取 2.list类型数据业务场景

电脑软件:推荐一款非常强大的pdf阅读编辑软件

目录 一、软件简介 二、功能介绍 1、界面美观,打开速度快 2、可直接编辑pdf 3、非常强大好用的注释功能 4、很好用的页面组织和提取功能 5、PDF转word效果非常棒 6、强大的OCR功能 三、软件特色 四、软件下载 pdf是日常办公非常常见的文档格式,…

基于RM编译码的协作MIMO系统误码率matlab仿真,对比不同RM编译码参数

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 MATLAB2013b 3.部分核心程序 ...................................................................... [V1,N1,K1,I1] f…

05 MIT线性代数-转置,置换,向量空间Transposes, permutations, spaces

1. Permutations P: execute row exchanges becomes PA LU for any invertible A Permutations P identity matrix with reordered rows mn (n-1) ... (3) (2) (1) counts recordings, counts all nxn permuations 对于nxn矩阵存在着n!个置换矩阵 , 2. Transpose: 2.…

前端性能优化 - 虚拟滚动

一 需求背景 需求:在一个表格里面一次性渲染全部数据,不采用分页形式,每行数据都有Echart图插入。 问题:图表渲染卡顿 技术栈:Vue、Element UI 卡顿原因:页面渲染时大量的元素参与到了重排的动作中&#x…

代码随想录 Day26贪心算法01-上

目录 前言:贪心无套路 本质: 两个极端 贪心的小例子 贪心无套路!!! LeetCode T455 分发饼干 题目思路: 1.优先考虑胃口:大饼干喂饱大胃口 2.优先考虑饼干:小饼干先喂饱小胃口 前言:贪心无套路 本质: 局部最优去推导全局最优 两个极端 贪心算法的难度一般要么特别简单,要…

Mac Intellij Idea get/set方法快捷键

Control Retrun(回车键) Command n 参考: Mac Intellij Idea get/set方法快捷键-CSDN博客

2018年亚太杯APMCM数学建模大赛A题老年人平衡能力的实时训练模型求解全过程文档及程序

2018年亚太杯APMCM数学建模大赛 A题 老年人平衡能力的实时训练模型 原题再现 跌倒在老年人中很常见。跌倒可能会导致老年人出现许多并发症,因为他们的康复能力通常较差,因此副作用可能会使人衰弱,从而加速身体衰竭。此外,对跌倒…