当前位置: 首页 > news >正文

分代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初体验|得物技术

相关文章:

分代ZGC详解

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

vue图片懒加载

Vue图片懒加载是一种优化页面性能的技术,它可以延迟加载页面上的图片,直到它们进入可见区域。这可以减少页面的加载时间,提高用户体验。 在Vue中实现图片懒加载可以使用第三方库vue-lazyload。首先需要安装该库: npm install vu…...

【c++】运算符重载实例

重载自增自减运算符 Intger num(2); num; num;对自增运算符的重载要区分前置和后置。在重载之前需要思考一个问题,num是返回一个临时变量还是num对象的本体。 为了解决这个问题可以考虑实现一个Inc_()函数和_Inc()函数分别模仿后置和前置的行为 Integer Inc_(){i…...

用*画田字形状,numpy和字符串格式化都可以胜任

numpy的字符型元素矩阵,可以方便画;直接python字符串手撕,也可以轻巧完成。 (本笔记适合熟悉循环和列表的 coder 翻阅) 【学习的细节是欢悦的历程】 Python 官网:https://www.python.org/ Free:大咖免费“圣经”教程《…...

搭建一个windows的DevOps环境记录

边搭建边记录,整个DevOps环境的搭建可能会很久。。。 一、安装Jenkins: 参考:Jenkins基础篇--windows安装Jenkins-CSDN博客 注意上面选择JDK的路径,选择到安装目录,该目录并不一定要在path中配置了(就是…...

漏洞扫描系统的主要功能有哪些

漏洞扫描系统是一种自动化的工具,用于发现和报告计算机网络系统中的安全漏洞。这些漏洞可能包括软件漏洞、配置错误、不安全的网络设备等。漏洞扫描系统的主要功能包括以下几个方面: 目标识别:漏洞扫描系统首先需要识别目标系统的基本信息&am…...

Spring Boot配置多个Kafka数据源

一、配置文件 application.properties配置文件如下 #kafka多数据源配置 #kafka数据源一,日志审计推送 spring.kafka.one.bootstrap-servers172.19.12.109:32182 spring.kafka.one.producer.retries0 spring.kafka.one.producer.properties.max.block.ms5000 #kafk…...

Learning Open-World Object Proposals without Learning to Classify(论文解析)

Learning Open-World Object Proposals without Learning to Classify 摘要1 介绍2 相关工作3 方法3.1 基线3.2 基于纯定位的对象性3.3. 对象定位网络 (OLN)4 实验4.1跨类泛化4.2.开放世界类不可知检测4.3更多的跨数据集泛化4.3.1 Objects365 泛化4.3.2 EpicKitchens 的泛化4.4…...

前端在项目中添加自己的功能页面

1.src—>mock–>sideMenue:边表(sidemenue)的子功能的添加:左边功能框中的显示 在相应的父功能添加子功能 id号不能和他人的一样,casecode:就是路由名字 title:中文名称 2.前后端接口(后端程序员给),定义好接口名称 src—>moudles—…...

数据库MySQL(二):DDL数据定义语言

数据定义语言(Data Definition Language,DDL) 该语言主要用于定义数据库对象,操作对象为数据库、表或字段。 数据库操作 # 查询所有数据库 SHOW DATABASES;# 查询当前数据库 SELECT DATABASE(); # 创建数据库 CREATE DATABASE […...

Spring FactoryBean 源码讲解

Spring FactoryBean 源码讲解 什么是Spring FactoryBean Spring FactoryBean是一个特殊的Bean,它实现了FactoryBean接口并重写了其getObject()方法,用于生产其他Bean的实例。在Spring容器启动时,会自动调用FactoryBean的getObject()方法来获…...

【C语言】零碎知识点|细节

除法运算符(/)的使用规则 在C语言中,除法运算符(/)的使用规则如下: 当两个整数相除时,结果也是一个整数。例如,如果A和B都是整数,那么A / B的结果也是一个整数。这意味着,除法运算的结果会忽略小数部分。例如,10 / 3 的结果是3,而不是3.3333。 当一个整数和一个浮点…...

电影评分数据分析案例-Spark SQL

# cording:utf8from pyspark.sql import SparkSession from pyspark.sql.types import IntegerType, StringType, StructType import pyspark.sql.functions as Fif __name__ __main__:# 0.构建执行环境入口对象SparkSessionspark SparkSession.builder.\appName(movie_demo)…...

vue如何使用冻结对象提升代码效率及其原理解析

先给大家伙整个实际工作中一定会碰到的问题 如下vue dome ,它的代码非常简单功能也1非常简单,就是一个按钮,点击后会显示有多少条数据 来看看源码, html部分就是一个按钮绑定了一个loadData事件,然后在p标签内展示了这个myData这个数据的长度 <template><div id&quo…...

基于深度学习网络的手势识别算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 clc; clear; close all; warning off; addpath(genpath(pwd)); rng(default)load gnet.mat[Pr…...

[论文笔记] 多语言模型中的负干扰研究结果和元学习算法

On Negative Interference in Multilingual Models: Findings and A Meta-Learning Treatment 多语言模型中的负干扰:研究结果和元学习解决办法 概述: 训练语料库大小(训练数据大小和 负干扰 无关)。 语言亲缘关系/语系 和 负干扰 有关。添加相似的语言并不能减轻负面干扰。…...

【OpenVINO】行人摔倒检测 — 基于 OpenVINO C# API 部署PP-Human-下篇

行人摔倒检测 — 基于 OpenVINO C# API 部署PP-Human 4. 配置 PP-Human_Fall_Detection 项目4.1 环境配置4.2 创建 AlxBoard_deploy_yolov8 项目4.3 添加项目源码4.4 添加 OpenVINO C# API4.5 添加 OpenCvSharp 5. 测试 PP-Human_Fall_Detection 项目5.1 创建视频读取器5.2 行人…...

运行报错(三)git bash报错fatal: detected dubious ownership in repository at

报错现象 在运行git 命令时&#xff0c;出现报错 “fatal: detected dubious ownership in repository at” 报错原因 文件夹的所有者和现在的用户不一致 栗子&#xff1a; 文件夹的所有者是root&#xff0c;而当前用户是admin 解决方案 方法一、 将文件夹的所有者替换成ad…...

nvm 的安装及使用

文章目录 一、nvm是什么&#xff1f;二、下载nvm三、在cmd控制台进行操作1、nvm 查询版本号2、查询可以下载的node版本3、安装指定版本4、查看已经安装的node版本5、切换node版本(如果失败那就用管理员身份打开cmd进行切换) 一、nvm是什么&#xff1f; nvm是一个node的版本管理…...

xcode Simulator 安装

xcode Simulator 安装 参考文档 xcode又又又升级了&#xff0c;升级完成之后不下载最新的 iOS 17 Simulator就不能编译运行了&#xff0c;只能静静的等他下载。但是离谱的是这个居然没有断点续下&#xff0c;每次都要重新下载&#xff0c;眼睁睁的看着下载了4个G然后断掉了从…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…...

家政维修平台实战20:权限设计

目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系&#xff0c;主要是分成几个表&#xff0c;用户表我们是记录用户的基础信息&#xff0c;包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题&#xff0c;不同的角色&#xf…...

Nuxt.js 中的路由配置详解

Nuxt.js 通过其内置的路由系统简化了应用的路由配置&#xff0c;使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.

ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #&#xff1a…...

【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error

在前端开发中&#xff0c;JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作&#xff08;如 Promise、async/await 等&#xff09;&#xff0c;开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝&#xff08;r…...

AI语音助手的Python实现

引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...