HotSpot虚拟机的几个实现细节

文章目录

    • STW
    • 安全点
    • 安全区域
    • 记忆集与卡表
    • 读写屏障

STW

收集器在根节点枚举这步都是必须要暂停用户线程的( STW ),如果不这样的话在根节点枚举的过程中由于引用关系在不断变化,分析的结果就不准确

安全点

收集器在工作的时候某些时间是需要暂停正在执行的用户线程的( STW ),这个暂停也并不是说用户线程在执行指令流的任意位置都能停顿下来开始垃圾收集, 而是需要等用户线程执行到最近的安全点后才能够暂停。

安全点如何选取呢?,安全点的选取基本是以:”是否具有让程序长时间执行的特征“为标准选定的,而最明显的特征就是指令序列的复用,主要有以下几点:

  • 方法调用
  • 循环跳转
  • 异常跳转

对于安全点另一个问题是:垃圾收集器工作时如何让用户线程都跑到最近的安全点停顿下来?有两种方案:

  • 抢先式中断:不需要用户代码主动配合,垃圾收集发生时,系统把用户线程全部中断,如果发现用户线程中断的地方不在安全点上,就恢复这个线程执行让它执行一会再重新中断。不过现在的虚拟机几乎没有采用这种方式。
  • 主动式中断: 当垃圾收集器需要中断线程的时候,不直接对线程操作,仅仅设置一个标志位,各个线程执行过程中会不停的去主动轮询这个标志,一旦发现中断标志为真时就自己再最近的安全点上主动挂起。

安全区域

安全点的设计似乎完美的解决了如何停顿用户线程,它能保证用户线程在执行时,不太长时间内就会遇到可进入垃圾回收的安全点,但是如果用户线程本身就没在执行呢?比如用户线程处于 sleep 或者 blocked 状态,这个时候它就无法响应虚拟机的中断请求,没办法主动走到安全的地方中断挂起自己,对于这种情况就必须引入安全区域( Safe Regin )来解决。

安全区域是指能够确保在某一段代码片段之中, 引用关系不会发生变化,因此,在这个区域中任意地方开始垃圾收集都是安全的。我们也可以把安全区域看作被扩展拉伸了的安全点。

当用户线程执行到安全区域里面的代码时,首先会标识自己已经进入了安全区域,这段时间里 JVM 要发起 GC 就不必去管这些线程了。 当线程要离开安全区域时,它要检查 JVM 是否已经完成了根节点枚举(或者其他 GC 中需要暂停用户线程的阶段):

  • 如果完成了,那线程就当作没事发生过,继续执行
  • 如果没有完成,他就必须一直等待,直到收到可以离开安全区域的信号为止

在这里插入图片描述

记忆集与卡表

在分代收集理论里面提到过一个跨代引用问题,为了解决跨代引用带来的问题,垃圾收集器在新生代建立了一个叫做:记忆集( Remembered Set )的数据结构存储老年代哪些区域存在跨代引用,以便在根节点扫描时将这些老年代区域加入 GC Roots 的扫描范围,这样避免将整个老年代都加入 GCRoots 的扫描范围

当然跨代引用的问题并非只在回收新生代才有,回收老年代也是一样的,所以需要更进一步理解记忆集的原理和实现方式。

记忆集定义:是一种用于记录从非收集区域指向收集区域的指针集合的象数据结构。
记忆集的实现:最常见的实现方式是通过卡表( Card Table )的方式去实现,卡表最简单的形式是一个字节数组(hotspot ),如下:

CARD_TABLE[this address >> 9 ] = 0 1

1、字节数组 CARD_TABLE 的每一个元素都对应着其标识的内存区域中一块特定大小的内存块,这个内存块被称作:卡页( Card Page ),卡页大小一般是2的N次幂, hotspot 中是2的9次幂(地址右移9位),即512字节。

2、如果卡表标识的起始地址是:0x0000,那数组的0,1,2号元素,分别对应的地址范围是:0x0000ox01ff,0x02000x03ff,0x0400~0x05ff,如下:

在这里插入图片描述

3、一个卡页的内存中通常包含不止一个对象,只要卡页内存中有一个或多个对象的字段存在跨代引用指针,那就将卡表对应字节数组元素的值标识位1,称之为 Ditry ,没有则标识位0,垃圾收集器工作时只要筛查 CARD_TABLE 中为1的元素,就能轻易找到哪些卡页内存块中包含跨代引用,就把这些内存块加入到 GC Roots 的扫描范围内。

读写屏障

目前已经解决了用记忆集来缩减存在跨代引用时 GC Roots 的扫描范围,但是还没解决卡表如何维护的问题,比如:何时将卡表变脏?

答案似乎明显:非收集区域存在收集区域的引用时,对应卡表元素就变脏,变脏的时间点原则上应发生在引用类型字段赋值的那一刻, 但问题是如何在引用类型字段赋值的那一刻去维护卡表呢?

如果是解释执行的字节码那相对好处理,虚拟机负责每条字节码的执行,有充分的介入空间,但如果是编译执行的场景呢?即时编译器编译后的代码已经是纯粹的机器指令了,所以必须找一个在机器码操作的层面,在赋值操作发生时来维护卡表。

hotspot 中是通过写屏障( write barrier )来维护的, 这里的读写屏障要和解决并发问题的 内存屏障 区分开来,这里的读写屏障类似于 spring 的AOP ,比如以下代码是一个卡表更新的简化逻辑

void oop_field_store( oop* field,oop new_value) {
//引用字段赋值
*field = new_value;
//写后屏障,完成卡表更新
post_write_barrier(field,new_value);
}

当然这里还需要解决一个问题:卡表在高并发场景下面临着 伪共享 问题,一般处理器的缓存行( cache line )大小是64字节,由于卡表一个元素占一个字节,64个卡表元素共享同一个缓存行,这64个卡表元素对应的卡页总大小内存为:64*512bytes=32M,也就是说如果不同线程更新的对象引用正好处在这32M内存区域内,就会导致更新卡表时正好写入同一个缓存行而影响性能。

为了解决伪共享的问题,简单的解决方案就是不采用无条件的写屏障,而是先检查卡标记,只有当卡表元素未被标记过时才将其标记为变脏,即更新卡表的逻辑变更如下:

if (CARD_TABLE[this address >> 9] != 0 ) {
CARD_TABLE[this address >> 9] = 0;
}

在jdk1.7之后 , hotspot 虚拟机增加了一个参数 -XX:+UseCondCardMark ,用来解决是否开启卡表更新前的条件判断,开启会增加一次额外的条件判断开销,但能够避免伪共享问题,两者各有性能损耗,是否开启需要根据实际情况来测试权衡,默认是关闭的。

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

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

相关文章

切勿安装这五款流氓软件,你中招了没

流氓软件,又称为恶意软件,是一类设计用来损害用户设备、窃取信息或干扰正常使用的程序。以下是五款臭名昭著的流氓软件介绍,提醒切勿安装,只能说一个比一个毒,你中招了没 可以去去虚拟机试试谁的毒更强一些&#xff0…

高工咨询:《2024中国人形机器人产业发展蓝皮书》

高工咨询所发布的《2024中国人形机器人产业发展蓝皮书》全面梳理了人形机器人产业的发展现状、政策环境、资本市场、技术发展、市场前景以及面临的机遇与挑战等情况。 人形机器人是当今世界科技领域最具潜力和前景的产业之一。随着科技的不断进步和人 工智能技术的快速发展&…

基于jeecgboot-vue3的Flowable增加表单功能(二)

因为这个项目license问题无法开源,更多技术支持与服务请加入我的知识星球。 接上一节 6、增加一个types.ts 类型 export interface FormForm {id: number | string | undefined;formName: string;formContent?: string;remark: string; } 7、api增加一个getForm…

Github Page 部署失败

添加 .gitmodules 文件 [submodule "themes/ayer"]path themes/ayerurl https://github.com/Shen-Yu/hexo-theme-ayer.git 添加 .nojekyll 文件

滚珠花键在工业自动化领域中有什么优势?

滚珠花键是工业自动化设备中重要的传动系统之一,不仅在工业自动化系统中有着广泛的运用,还在机械制造领域、航空航天领域、工业汽车领域、工业机器人、高速铁路、新能源领域 等都得到广泛应用。由于具有高精度、高承载、耐磨损、传递扭矩大等特点&#x…

K8s集群中的Pod调度约束亲和性与反亲和性

前言 在 K8s 集群管理中,Pod 的调度约束——亲和性(Affinity)与反亲和性(Anti-Affinity)这两种机制允许管理员精细控制 Pod 在集群内的分布方式,以适应多样化的业务需求和运维策略。本篇将介绍 K8s 集群中…

airtest做web端UI自动化实战

安装 官网下载客户端 airtest库安装 pip install airtest pip install pocoui脚本录制 利用airtest客户端录制脚本 web端辅助插件-selenium windows打开: 设置chrome路径 开始调式录制 脚本运行 # -*- coding: utf-8 -*- """ Time : 2024/5/…

龙迅LT86102UXE HDMI 2.0分配两个HDMI 2.0输出,支持标准4K60HZ,内置MCU供电可自动操作

龙迅LT86102UXE描述: Lontium LT86102UXE HDMI2.0分配器具有1:2的分配器,符合HDMI2.0/1.4规范,最大6Gbps高速数据速率,自适应均衡RX输入和预先强调的TX输出,以支持长电缆应用程序,内部TX通道交…

用大模型搭建一个自己的新闻小助手

背景 信息快速增长的时代,及时获取到有价值的资讯是一件很必要的事情。已经有各类新闻app和获取信息的渠道了,为什么还需要在构建一个小助手来获取新闻资讯呢?其实原因很简单各类新闻app服务的是具体一类人群,个人和人群还是有偏…

kafka-消费者组-发布订阅测试

文章目录 1、发布订阅测试1.1、创建消费者4并指定组 my_group21.2、列出所有的消费者组1.3、查看 my_group2 组的详细信息1.4、发送第六条消息accomplish1.4.1、查看 my_group1 组的详细信息1.4.2、查看 my_group2 组的详细信息 1、发布订阅测试 接着上一篇点对点博客测试 kafk…

LabVIEW控制Trio控制器

将LabVIEW与Trio控制器结合,可以实现对复杂运动系统的控制和监测。以下是详细的方法和注意事项: 一、准备工作 软件安装: 安装LabVIEW开发环境,确保版本兼容性。 安装Trio控制器的相关驱动程序和软件,如Trio Motion …

出现 Transaction rolled back because it has been marked as rollback-only 解决方法

目录 1. 问题所示2. 原理分析3. 解决方法1. 问题所示 用户反馈的Bug如下所示: Transaction rolled back because it has been marked as rollback-only截图如下: 浏览器终端同样显示: 2. 原理分析 错误表明,在事务的生命周期内,遇到了某个异常或条件,导致该事务被标记…

Shell编程中的循环语句和函数

一、for循环语句 当面对各种列表重复任务时,使用简单的if语句已经难以满足需求,这时就需要for循环语句。for语句的结构为: for 变量 in 取值列表 do 命令序列 done 使用for循环语句时,需要指定一个变量及取值列表,针对…

2、python环境的安装-mac系统下

打开官网,downloads下边有macOS,点击: 选择最新版本,点击,进入下边的页面,一直往下滑,看到files中有个macOS的版本,点击下载 点击下载后是pkg的安装包,点击安装。 一步步…

鸿蒙OS开发:【一次开发,多端部署】(app市场首页)项目

一多应用市场首页 介绍 本示例展示了应用市场首页,页面中包括Tab栏、运营横幅、精品应用、精品游戏等。 本示例使用一次开发多端部署中介绍的自适应布局能力和响应式布局能力进行多设备(或多窗口尺寸)适配,保证应用在不同设备或…

蓝桥杯第1022题 玩具蛇 基础DFS C++ Java

题目 思路和解题方法 问题理解:此题要求找出将一条由16节正方形构成的玩具蛇放入4x4的方格中的不同方式数。每节蛇可以是直线或直角转弯,且蛇的形状需要完全覆盖盒子里的16个格子,每个格子仅被蛇的一个部分占据。 状态表示:使用一…

爷爷看了都会,打工人必备的摸鱼AI神器!免费!

去年,AI技术无疑成为了最为引人注目的焦点,层出不穷的创新应用令人目不暇接。尽管许多人对这股AI热潮的持久性持怀疑态度,但现实却用事实给予了最有力的反驳。AI所展现出的强大生产力,足以令人刮目相看。 而今年以来,…

VUE3学习第一篇:启动ruoyi

1、找到ruoyi的vue3版本 然后下载代码到本地, 我刚开始用的nodejs14报错, 后面换成nodejs16,启动前端成功了。 页面如下图所示

【JPCS出版,EI稳定检索会议推荐】第四届计算机、遥感与航空航天国际学术会议(CRSA 2024)已成功申请JPCS出版,火热征稿中!

【EI核心、Scopus】第四届计算机、遥感与航空航天国际学术会议(CRSA 2024)将于2024年7月5-7日在日本大阪举行。计算机、遥感与航空航天国际学术会议为来自世界各地的研究学者、工程师、学会会员以及相关领域的专家们提供一个关于“计算机科学”、“遥感技…

体验SmartEDA的高效与便捷,电子设计从未如此简单

SmartEDA:革新电子设计,让高效与便捷触手可及 在快节奏的现代生活中,科技日新月异,各行各业都在寻求更高效、更便捷的解决方案。对于电子设计行业而言,SmartEDA的出现,无疑是一场革命性的变革。它以其高效…