0

0

什么是Java中的跨代引用问题_记忆集(Remembered Set)与卡表应用

P粉602998670

P粉602998670

发布时间:2026-02-25 15:31:03

|

204人浏览过

|

来源于php中文网

原创

跨代引用迫使gc扫描老年代中可能指向年轻代的引用,记忆集(rset)通过卡表和写屏障精准标记脏卡页,避免全老年代扫描;g1为每个region维护独立rset,提升并发效率但增加内存与性能开销,cms则仅用粗粒度卡表,不维护rset,导致浮动垃圾增多。

什么是java中的跨代引用问题_记忆集(remembered set)与卡表应用

跨代引用为什么会让GC变慢

新生代GC(比如Minor GC)只扫描年轻代对象,但若老年代对象引用了年轻代对象,就可能漏掉本该回收的年轻代对象——所以JVM必须知道“哪些老年代区域可能持有对年轻代的引用”,否则就得扫描整个老年代,开销爆炸。

记忆集(Remembered Set,简称RSet)就是干这个的:它记录了老年代中哪些内存块(比如卡页)里存有指向年轻代的引用。每次老年代对象修改引用时,JVM会检查目标是否在年轻代,若是,就标记对应卡页为“脏”。后续Minor GC只需扫描这些脏卡页里的对象,而不是整块老年代。

  • RememberedSet不是Java代码能直接访问的类,而是HotSpot VM内部结构,由GC算法(如G1、ZGC)自动维护
  • 卡表(Card Table)是RSet的底层实现之一:把老年代划分为512字节/块的“卡”,每卡用1字节标记是否脏;card table本身是byte数组,地址映射靠位运算计算
  • 写屏障(Write Barrier)是触发卡表更新的关键机制:所有obj.field = new_obj这类赋值,在编译后都会插入一段检查逻辑,判断new_obj是否在年轻代,是则标记对应卡为脏

G1中的RSet和卡表怎么配合工作

G1把堆切成大小相等的Region,每个Region都维护一个独立的RSet,记录“谁指向我”。这比全局卡表更精细:比如Region A的RSet里存着Region B、C中具体哪些卡页改写了对A的引用。

这种设计让并发标记和混合GC更高效,但也带来额外内存开销——RSet本身要占堆空间,且Region越小、RSet数量越多,总开销越大。

立即学习Java免费学习笔记(深入)”;

Gatekeep
Gatekeep

Gatekeep AI是一个专注于将文本转化为教学视频的智能教学工具,主要用于数学和物理等学科的教育。

下载
  • 默认卡页大小是512字节,不可配置;-XX:G1HeapRegionSize影响Region大小,间接影响RSet粒度
  • RSet更新由G1PostBarrier写屏障触发,它比CMS的卡表写屏障更重(因需维护多对多映射),所以G1对mutator性能影响略高
  • 如果应用频繁在老年代对象中修改指向新生代的引用(如缓存池反复替换value),会导致大量卡页变脏,Minor GC前扫描RSet变慢——这是Young GC time increasing的常见隐形原因

为什么CMS不依赖RSet而用卡表就够了

CMS是“标记-清除”老年代收集器,它不移动对象,也不做跨代精确扫描;它的跨代引用处理很粗暴:在Minor GC时,直接把整个young_gen加入GC Roots,并扫描老年代中所有已知的“跨代引用卡页”(即卡表中标记为脏的页)。

也就是说,CMS的卡表只用于避免全老年代扫描,不构建对象级引用关系,也没有Region级RSet的概念。

  • CMS启用卡表靠-XX:+UseConcMarkSweepGC自动开启,卡表结构与G1相同,但语义不同:CMS卡表只标记“可能含跨代引用”,不区分引用方向或目标Region
  • 因为不维护RSet,CMS在老年代并发标记阶段无法知道“哪个老年代对象被年轻代引用”,所以无法提前清理无用跨代指针,容易导致浮动垃圾增多
  • 一旦出现Concurrent Mode Failure,CMS被迫退化为Serial Old,此时卡表失效,所有跨代引用逻辑回退到全堆扫描

排查RSet相关性能问题的实际抓手

没有直接日志说“RSet太大”,但可以从GC日志里反推:关注Minor GC中[RS][SATB]阶段耗时(G1),或[CardTableScanning]时间(CMS)。这些字段背后就是RSet操作。

另外,jstat -gc <pid></pid>输出里的EC(Eden Capacity)、EU(Eden Used)变化正常,但YGC次数没涨、YGCT却飙升,大概率是RSet扫描拖慢了。

  • -XX:+PrintGCDetails -XX:+PrintGCTimeStamps打开详细GC日志,找类似[RS Threads: 8][Update RS (ms): Min: 0.2, Avg: 1.7, Max: 4.3]这样的行
  • G1下可加-XX:+G1PrintRegionLivenessInfo看各Region RSet大小,但仅限调试,生产慎用(性能损耗大)
  • 真正压测时发现RSet相关阶段占比持续>30%,说明跨代引用太密集——这时该检查业务代码:是不是在静态map里长期持有新创建的对象?或者用ThreadLocal<object></object>存了短命对象?

跨代引用本身无法消除,但RSet的负担取决于“谁在什么时候改了什么引用”。写屏障开销藏得深,日志不报错,只悄悄拖慢GC——这点最容易被忽略。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

423

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

596

2023.08.10

golang map内存释放
golang map内存释放

本专题整合了golang map内存相关教程,阅读专题下面的文章了解更多相关内容。

77

2025.09.05

golang map相关教程
golang map相关教程

本专题整合了golang map相关教程,阅读专题下面的文章了解更多详细内容。

36

2025.11.16

golang map原理
golang map原理

本专题整合了golang map相关内容,阅读专题下面的文章了解更多详细内容。

67

2025.11.17

java判断map相关教程
java判断map相关教程

本专题整合了java判断map相关教程,阅读专题下面的文章了解更多详细内容。

46

2025.11.27

页面置换算法
页面置换算法

页面置换算法是操作系统中用来决定在内存中哪些页面应该被换出以便为新的页面提供空间的算法。本专题为大家提供页面置换算法的相关文章,大家可以免费体验。

474

2023.08.14

batoto漫画官网入口与网页版访问指南
batoto漫画官网入口与网页版访问指南

本专题系统整理batoto漫画官方网站最新可用入口,涵盖最新官网地址、网页版登录页面及防走失访问方式说明,帮助用户快速找到batoto漫画官方平台,稳定在线阅读各类漫画内容。

62

2026.02.25

Steam官网正版入口与注册登录指南_新手快速进入游戏平台方法
Steam官网正版入口与注册登录指南_新手快速进入游戏平台方法

本专题系统整理Steam官网最新可用入口,涵盖网页版登录地址、新用户注册流程、账号登录方法及官方游戏商店访问说明,帮助新手玩家快速进入Steam平台,完成注册登录并管理个人游戏库。

6

2026.02.25

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 3.9万人学习

C# 教程
C# 教程

共94课时 | 10.2万人学习

Java 教程
Java 教程

共578课时 | 72.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号