JVM是如何解决跨代引用的?

JVM是如何解决跨代引用的?

  • 跨代引用问题
    • 如何解决跨代引用
      • 记忆集(Remembered Set)
      • 卡表
    • 写屏障

跨代引用问题

假如要现在进行一次只局限于新生代区域内的收集(Minor gc),但新生代的对象1在老年代中被引用,为了找出该区域(新生代)中所有的存活对象,不得不在固定的gc roots之外,在额外遍历整个老年代中所有对象来确保可达性分析结果的正确性。
遍历整个老年代所有对象的方案虽然可行,但是会给内存回收带来很大的性能负担。

实时上并不是只有新生代、老年代才有跨代引用的问题,所有涉及部分区域手机行为的垃圾收集器,典型的如G1、ZGC收集器,都会面临同样的问题。

如何解决跨代引用

先说结论,JVM是使用 写屏障 + 卡表 解决的。

  • 首先,跨代引用是少数的,例如:某个新生代对象存在跨代引用,由于老年代对象难以消亡,就会导致新生代对象在收集时同样得已存活,进而在年龄增长之后晋升到老年代中了。
  • 所以就不用为了少量的跨代引用扫描整个老年代,只需要在新生代建立一个全局的数据结构(该结构被称为 记忆集,Rember Set),标识出老年代的哪一块内存存在跨代引用,此后发生minor gc时,只有包含了跨代引用的小块内存里的对象才会被加入gc root进行扫描。
  • 个人理解,card table是用来划分老年代的,即把老年代划分多个大小相等的连续区域,而Rember set中记录了卡表的位置。

记忆集(Remembered Set)

一种记录 从非收集区域(如老年代) 指向 收集区域(如年轻代)的指针集合的抽象数据结构,在对象层面来说就是非收集区域对收集区域对象的引用记录。
它存放在收集区域,比如在新生代里面存放着老年代对新生代的每一个引用,这样在收集新生代的时候,我们就可以根据记忆集知道哪些对应被老年代对象引用了,不能回收,这就解决了跨代引用过的问题。

记忆集根据记录的精度可以分三类实现方式:

  • 字长精度:记录的是老年代指向新生代地址。
  • 对象精度:记录的是老年代引用的新生代对象。
  • 卡精度:记录的是新生代一段地址是否存在被老年代引用的记录

卡表

是以第三种卡精度的方式实现的记忆集,也是目前最常用的方式。记忆集是抽象的概念,而卡表就是记忆集的一种具体实现。

卡表最简单的形式可以是一个字节数组,HotSpot就是这样实现的。
CARD_TABLE [this address >> 9] = 0;

把地址的值右移9位相当于除于512就是卡表索引,每字节512为一组对应卡表同一个元素,一组就是一个卡页,如果这个卡页中只要有一个对象被其他区域对象所引用,对应卡表元素的值就变成1,也就是所谓的元素变脏。

在垃圾回收时,只要筛选出卡表中变脏的元素,就能轻易得出哪些卡页对应的内存包含跨代指针,把他们加入GC Rootsz中一并扫描。

写屏障

可以看成是虚拟机层面在“引用类型字段赋值”这个动作的AOP切面,引用对象赋值的时候产生一个环形通知,进行一些额外的处理,这样就是引用对象赋值这个操作都在写屏障的覆盖范围内,赋值前的写屏障叫写前屏障,赋值后的写屏障叫写后屏障。
卡表的更新,就是通过写屏障写入的。

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

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

相关文章

掌握Go语言:深入encoding/gob包的高效数据序列化

掌握Go语言:深入encoding/gob包的高效数据序列化 引言理解Gob和它的使用场景Gob的概念和设计目标Gob的适用场景和优势 开始使用Gob基本的Gob编码和解码示例代码编码(序列化)解码(反序列化) Gob编码高级应用自定义类型的…

c语言常见上机题

快速排序 快排很容易进入无限递归&#xff0c;写的时候要注意边界问题 #include<iostream>using namespace std;int n;const int N 1e6 10;void qsort(int a[],int l,int r){if(l>r) return;int xa[l],il-1,jr1;while(i<j){do i;while(a[i]<x);do j--;while(…

MFC中手动create创建的窗口,如何销毁释放?

在MFC中&#xff0c;当你手动创建一个窗口&#xff08;例如使用Create函数而不是通过对话框模板创建&#xff09;&#xff0c;你需要确保在适当的时候正确地销毁和释放该窗口。这通常涉及删除窗口对象并调用其析构函数&#xff0c;这将负责清理与窗口相关联的资源。 以下是一些…

【Java语言】遍历List元素时删除集合中的元素

目录 前言 实现方式 1.普通实现 1.1 使用【for循环】 方式 1.2 使用【迭代器】方式 2.jdk1.8新增功能实现 2.1 使用【lambda表达式】方式 2.2 使用【stream流】方式 注意事项 1. 使用【for循环】 方式 2. 不能使用增强for遍历修改元素 总结 前言 分享几种从List中移…

基于 K8s 容器集群的容灾架构与方案

作者&#xff1a;庄宇 在设计系统架构时&#xff0c;我们必须假设任何组件和任何基础设施可能会在任何时间失效&#xff0c;例如&#xff1a;自然灾害&#xff0c;电力中断&#xff0c;网络中断&#xff0c;错误的系统变更等。为了应对挑战&#xff0c;我们必须设计合适的容灾…

在centos8中部署Tomcat和Jenkins

参考链接&#xff1a;tomcat安装和部署jenkins_jenkins和tomcat-CSDN博客 1、进入centos中 /usr/local 目录文件下 [rootlocalhost webapps]# cd /usr/local2、使用通过wget命令下下载tomcat或者直接在官网下载centos版本的包后移动到centos中的local路径下 3、下载tomcat按…

VUE3内置组件Transition的学习使用

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 更多nbcio-boot功能请看演示系统RuoYi-Nbcio亿事达企业管理平台 gitee源代码地址 后端代码&#xff1a;…

详解Postman使用

简介&#xff1a; 1.简介 PostMan&#xff0c;一款接口调试工具。 特点&#xff1a; 可以保留接口请求的历史记录 可以使用测试集Collections有效管理组织接口 可以在团队之间同步接口数据 1.简介 PostMan&#xff0c;一款接口调试工具。 特点&#xff1a; 可以保留接口请求…

从0到1入门C++编程——12 演讲比赛流程管理系统

文章目录 一、创建类并显示菜单二、退出管理系统三、开始演讲比赛四、查看往届记录五、清空比赛记录六、案例源代码 演讲比赛流程管理系统 比赛规则&#xff1a;演讲比赛共有12个人参加&#xff0c;比赛分两轮进行&#xff0c;第一轮为淘汰赛&#xff0c;第二轮为决赛。每名选手…

HTML万字学习总结

html文本标签特殊符号图片音频与视频超链接表单列表表格语义标签(布局) html文本标签 标签简介根目录规定文档相关的配置信息&#xff08;元数据元素表示文档的内容表示那些不能由其它 HTML 元相关元素&#xff08;(<base>、<link>, <script>、<style>…

今日AI:GPT-4.5意外曝光可能6月发布、UP主借AI识别情绪播放量186万、全球首个AI程序员诞生

欢迎来到【今日AI】栏目!这里是你每天探索人工智能世界的指南&#xff0c;每天我们为你呈现AI领域的热点内容&#xff0c;聚焦开发者&#xff0c;助你洞悉技术趋势、了解创新AI产品应用。 新鲜AI产品点击了解:AIbase - 智能匹配最适合您的AI产品和网站 &#x1f4e2;一分钟速…

Netty优化

文章目录 概述优化方法性能篇网络参数优化业务线程池的必要性共享 ChannelHandler设置高低水位线GC 参数优化线程绑定 高可用篇连接空闲检测流量整形堆外内存泄漏排查思路Netty 自带检测工具二分排查法&#xff1a;笨方法解决大问题 概述 netty 是一种异步的、基于事件驱动的网…

Elastic boosting的使用

boosting介绍 Boosting查询允许您降低与负面查询匹配的文档的相关性评分 boosting语法 GET /_search {"query": {"boosting": {"positive": {"term": {"text": "apple"}},"negative": {"term&q…

如何拆解技术瓶颈的难点

以大化小的思路 解决一个一个小问题从而解决最终问题 三段论&#xff1a; 抽象能力 职责领域划分 分层构建解决方案 案例&#xff1a;全局分布式事务的解决方案 抽象能力&#xff1a;全局分布式 是由一个个小的事务组合而成的&#xff0c;其中一个分布式事务出现问题&#xff…

亚马逊Bedrock引领生成式AI创新,Claude 3模型家族开启新时代

近日&#xff0c;亚马逊宣布其云计算平台亚马逊Bedrock已成为构建和扩展基于大型语言模型&#xff08;LLM&#xff09;和其他基础模型&#xff08;FMs&#xff09;的生成式AI应用的最佳平台。Anthropic公司开发的Claude模型家族&#xff0c;作为高性能FMs的代表&#xff0c;正在…

探索考古文字场景,基于YOLOv8全系列【n/s/m/l/x】参数模型开发构建文本考古场景下的甲骨文字符图像检测识别系统

甲骨文是一种非常历史悠久的古老文字&#xff0c;在前面我们基本上很少有涉及这块的内容&#xff0c;最近正好在做文字相关的项目开发研究&#xff0c;就想着基于甲骨文的场景来开发对应的检测识别系统&#xff0c;在前文中我们基于YOLOv5、YOLOv7和YOLOv9开发构建了在仿真数据…

激活函数Mish

paper&#xff1a;Mish: A Self Regularized Non-Monotonic Activation Function official implementation&#xff1a;https://github.com/digantamisra98/Mish 背景 在早期文献中&#xff0c;Sigmoid和TanH激活函数被广泛使用&#xff0c;随后在深度神经网络中失效。相比于…

Redis 创建群时报错 Node XXX is not empty

在创建 Redis 集群时报错[ERR] Node XXX is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0. 主要原因是 RDB 或者 AOF 文件中有数据&#xff0c;redis集群搭建的时候需要所有节点都为 空&#xff0c;不…

【组件初始化链条】简化Unity组件的初始化

简介 在游戏脚本中我们通过借助GetComponent或TryGetComponent方法获取组件&#xff0c;所以当需要获取较多组件时&#xff0c;我们不可避免地要书写一些重复代码&#xff0c;为了提升代码简洁程度&#xff0c;简化组件初始化逻辑&#xff0c;本文以"组件初始化链条"…

Springboot的配置文件及其优先级

配置文件 内置配置文件 配置文件的作用&#xff1a;修改SpringBoot自动配置的默认值&#xff1b;SpringBoot在底层都给我们自动配置好&#xff1b;SpringBoot使用一个全局的配置文件&#xff0c;配置文件名是固定的&#xff1a; application.propertiesapplication.yml 以上…