HotSpot虚拟机的几个实现细节

news2024/9/25 7:16:35

文章目录

    • 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.coloradmin.cn/o/1701162.html

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

相关文章

如何设置XHSC(华大)单片机的IO口中断

XHSC(华大)单片机IO口中断使用 一、代码说明 华大单片机的历程在华大或者小华的官网上都可以下载到,但是我们下载的历程基本注释都是非常简单,有的还没有注释;再加上小华跟华大的历程在代码架构上有所区别,所以新手在直接调用华大或者小华历程后,历程代码的可读性并不…

解析气膜场馆造价—轻空间

随着社会的发展和对环保及时间成本的重视,气膜场馆逐渐成为众多体育场馆的首选建筑模式。气膜建筑包括气膜篮球场、气膜室内足球场、气膜羽毛球场、气膜乒乓球馆、气膜网球场以及气膜滑冰场等,因其多项优势受到广泛应用。 气膜场馆的显著特点 1. 气膜场馆…

不可错过的数据存储指南:JVS物联网平台存储策略详解

在物联网时代,数据的采集、存储和分析成为了关键环节。随着设备点位不断生成大量数据,如何高效地管理和保存这些数据,同时考虑存储成本和后续的数据分析价值,成为了亟待解决的问题。JVS物联网平台提供了灵活多样的存储策略&#x…

安泰电子:使用高压放大器时有哪些需要注意的呢

随着科技的不断进步,高压放大器在各种科学实验、工程应用和产业生产中扮演着重要的角色。然而,由于高压放大器的特殊性,使用时需要特别小心和谨慎。下面将详细介绍使用高压放大器时需要注意的事项,以确保安全、稳定地进行实验和应…

搭载昇腾310NPU的Orange Pi AIpro开箱体验以及深度学习样例测试

Orange Pi AIpro开箱体验以及样例测试 随着人工智能和物联网技术的快速发展,单板计算机(Single Board Computer, SBC)在创客和开发者社区中越来越受到欢迎。我最近入手了一款高性能的单板计算机——Orange Pi AIpro。 在入手此款AI开发板之…

【BI 可视化插件】怎么做? 手把手教你实现

背景 对于现在的用户来说,插件已经成为一个熟悉的概念。无论是在使用软件、 IDE 还是浏览器时,插件都是为了在原有产品基础上提供更多更便利的操作。在 BI 领域,图表的丰富性和对接各种场景的自定义是最吸引人的特点。虽然市面上现有的 BI 软…

如何理解 Java 类和对象

Java 中的类和对象是学习 Java 编程的基础之一。类是 Java 中的核心概念之一,它提供了一种组织和封装数据以及相关行为的方式。对象是类的实例,它是在运行时创建的,具有特定的状态和行为。 类和对象的概念 1. 类(Class&#xff…

Micro SD封装是什么?

我们了解客户对于Micro SD封装的疑问。在这篇文章中,我们将详细解释Micro SD封装是什么,以及其在存储领域的技术原理和应用情况,帮助客户更好地理解这一技术。 1. Micro SD封装的定义 Micro SD封装是指一种特定尺寸的存储芯片封装方式&#x…

汇凯金业:纸黄金和实物黄金的价格有什么区别

纸黄金和实物黄金的价格主要受到全球黄金市场行情的影响,二者的基础价格并无太大差异,但在具体交易时,可能会存在一些价格上的区别,这些差异主要来自以下几个方面: 交易费用与管理费:纸黄金交易通常需要支…

操作系统实战(四)(linux+C语言)

目录 实验目的 前提知识 实验题目 题目分析 实验程序 头文件 头文件实现 核心代码文件 (各类进程) 生产者 抽烟者A 抽烟者B 抽烟者C makefile文件 实验运行 运行结果分析 总结 实验目的 加深对并发协作进程同步与互斥概念的理解&…

学浪视频怎么下载保存到本地

你是否曾经因为想要保存一份珍贵的学浪视频却苦于无法下载而感到烦恼?现在,我将向你揭示一个简单易行的方法,让你轻松地将学浪视频保存到本地,随时随地享受学习的乐趣。你是否曾经因为想要保存一份珍贵的学浪视频却苦于无法下载而…

大模型的发展方向:让大模型感知人类所处的物理世界,文字、听、看、闻、触摸、动手操作等信息接收和输出能力,向物理世界学习 大模型开发者方向

大模型的发展方向非常广泛,除了让大模型感知人类所处的物理世界,通过文字、听觉、视觉、嗅觉、触觉和动手操作等信息接收能力,还包括以下几个重要的方向: 多模态学习与融合: 多模态感知:整合来自不同感知渠…

【Linux】TCP的三次握手和四次挥手

三次握手 在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。注意!三次握手只是用来建立连接用的,和TCP可靠稳定没有关系,TCP的可靠是通过重传和检错等机制实现的。 默认创建一个socket后&#xff…

瑜伽馆约课会员管理系统小程序的作用是什么

瑜伽馆有着众多学员,如瘦身、改变气质、减脂塑形等往往属于长期多次跟随教练学习,或是自己在家里学习等,对商家来说,品牌宣传、吸引客户到店以及长期经营、提高自身服务效率是重中之重。 客户多次进店享受服务的同时还需要悦己&a…

深入理解SVM和浅层机器学习算法的训练机制

深入理解SVM和浅层机器学习算法的训练机制支持向量机(SVM)的训练过程SVM的基本概念SVM的损失函数训练方法 浅层机器学习算法的训练机制决策树K-最近邻(K-NN)朴素贝叶斯 结论 深入理解SVM和浅层机器学习算法的训练机制 在探讨浅层…

悲痛都会过去,唯有当下值得珍惜

在生活的长河中,我们都会经历各种各样的悲痛与挫折,无论是来自原生家庭的困扰,婚姻中的曲折,还是小时候的创伤、男女关系中的纠葛、校园时期的霸凌。然而,当我们回首过去,曾经以为无法逾越的痛苦&#xff0…

javaEE—图书管理系统(基础代码版)

前言: 本篇博客是集合了javaEE所学的知识构建的一个基础框架,讲述着面向对象的过程是如何做到多对象交互协作完成框架的构建的。利用了数组,接口,类和对象,抽象类,Object类等知识来完成。 后续会加入数据…

记一次绕过宝塔防火墙的BC站渗透

0x00 信息收集 由于主站存在云waf 一测就封 且初步测试不存在能用得上的洞 所以转战分站 希望能通过分站获得有价值的信息 这是一个查询代理帐号的站 url输入admin 自动跳转至后台 看这个参数 猜测可能是thinkCMF 0x01 getshell thinkcmf正好有一个RCE 可以尝试一下 ?afetc…

[HDCTF 2023]爬过小山去看云(HILL密码,云影密码)

题目: 我们看到给出了矩阵[3 4 19 11] 1:利用在线工具进行解码Practical Cryptography 2:解码完成后所得结果翻译之后是数字,提取后842084210884024084010124,看到只含有01248便猜测时云影密码,利用脚本进行解密。 …

惠海 H6901B升压恒流3.7V 7.4V 12V 24V 30V 36V 48V 60V 80V 100V调光无频闪细腻顺滑

H6901B是一款升压型LED恒流驱动芯片,具有良好稳定性的特点。H6901B的主要特点包括宽输入电压范围(2.7V-100V)、高工作频率(1MHz)以及多种保护功能(如芯片供电欠压保护、过温保护、软启动等)。此…