精华内容
下载资源
问答
  • 2021-02-21 15:42:07

    当我们进行young gc时,我们的gc roots除了常见的栈引用、静态变量、常量、锁对象、class对象这些常见的之外,如果老年代有对象引用了我们的新生代对象,那么老年代的对象也应该加入gc roots的范围中,但是如果每次进行young gc我们都需要扫描一次老年代的话,那我们进行垃圾回收的代价实在是太大了,因此我们引入了一种叫做记忆集的抽象数据结构来记录这种引用关系。

    什么是记忆集?

    记忆集是一种用于记录从非收集区域指向收集区域的指针集合的数据结构。

    如果我们不考虑效率和成本问题,我们可以用一个数组存储所有有指针指向新生代的老年代对象。但是如果这样的话我们维护成本就很好,打个比方,假如所有的老年代对象都有指针指向了新生代,那么我们需要维护整个老年代大小的记忆集,毫无疑问这种方法是不可取的。因此我们引入了卡表的数据结构

    什么是卡表?

    记忆集是我们针对于跨代引用问题提出的思想,而卡表则是针对于该种思想的具体实现。(可以理解为记忆集是结构,卡表是实现类)

    在hotspot虚拟机中,卡表是一个字节数组,数组的每一项对应着内存中的某一块连续地址的区域,如果该区域中有引用指向了待回收区域的对象,卡表数组对应的元素将被置为1,没有则置为0;下图为卡表的一个实现,某块内存的地址向右移动9位(相当于除以512)定位到一个卡表元素,也就是说,内存中每512字节的连续区域会被定位到同一片卡表区域,如果卡表对应元素为1则代表该512个字节所在区域中有指向的指针。

    CARD_TABLE [this address >> 9] = 0; 
    

    写屏障(Write Barrier)

    我们每次对引用进行改变时,我们在程序中并没有手动去维护卡表的信息,那么卡表信息的维护到底是如何进行的呢,这就依赖于我们的写屏障功能。

    写屏障可以理解为对于我们引用类型字段复制的AOP操作。在赋前的部分的写屏障叫作写前屏障(Pre-Write Barrier),在赋值后的部分的写屏障叫作写后屏障(PostWrite Barrier)。

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

    G1的记忆集

    上述的卡表机制基本上适用于CMS垃圾回收器,因为CMS垃圾回收器只需要在young gc时维护老年代对新生代的引用即可,但是G1垃圾回收器不一样,因为G1垃圾回收器是基于分区模型的,所以每一个Region需要知道有哪些region的引用指向了它,并且这些region是不是本次垃圾回收区域的一部分。因此G1垃圾回收器不能简单的只维护一个卡表(卡表只能简单的知道某块内存区域有没有引用收集区域的对象,但是不能知道到底是谁引用了自己),所以在G1垃圾回收器的记忆集的实现实际上是基于哈希表的,key代表的是其他region的起始地址,value是一集合,里面存放了对应区域的卡表的索引,因此G1的region能够通过记忆集知道,当前是哪个region有引用指向了它,并且能知道是哪块区域存在指针指向。

    但是大家应该能注意到,每个region都维护一个记忆集,内存占用量肯定很大,这也就是为什么G1垃圾回收器比传统的其他垃圾回收器要有更高的内存占用。据统计G1至少要耗费大约10%-20%的Java堆空间lai’wei’hu收集器的工作。

    更多相关内容
  • 记忆集与卡表

    2021-12-18 22:29:41
    记忆集与卡表 为什么需要记忆集? 跨代引用假说(IntergenerationalReferenceHypothesis):跨代引用相对于同代引用来说仅占极少数。 存在互相引用关系的两个对象,是应该倾向于同时生存或者同时消亡的。举个例子,如果...

    记忆集与卡表

    为什么需要记忆集?

    跨代引用假说(IntergenerationalReferenceHypothesis):跨代引用相对于同代引用来说仅占极少数。

    存在互相引用关系的两个对象,是应该倾向于同时生存或者同时消亡的。举个例子,如果某个新生代对象存在跨代引用,由于老年代对象难以消亡,该引用会使得新生代对象在收集时同样得以存活,进而在年龄增长之后晋升到老年代中,这时跨代引用也随即被消除了。

    这时候便引出了记忆集(RememberedSet)概念。用以避免把整个老年代加进GCRoots扫描范围。事实上并不只是新生代、老年代之间才有跨代引用的问题,所有涉及部分区域收集(PartialGC)行为的垃圾收集器,典型的如G1、ZGC和Shenandoah收集器,都会面临相同的问题。

    实际上就是一种备忘录思想,空间换时间。

    什么是记忆集

    记忆集是一种用于记录从非收集区域指向收集区域的指针集合的抽象数据结构。

    卡表

    卡表(CardTable)是记忆集一种粗粒度的实现方式。来节省存储和维护成本。(由AntonyHosking在1993年发表的论文《Rememberedsetscanalsoplaycards》中提出)。

    在这里插入图片描述

    一种简单的数组结构。字节数组CARD_TABLE的每一个元素都对应着其标识的内存区域中一块特定大小的内存块,这个内存块被称作“卡页”(CardPage)。一般来说,卡页大小都是以2的N次幂的字节数,通过上面代码可以看出HotSpot中使用的卡页是2的9次幂,即512字节(地址右移9位,相当于用地址除以512)。那如果卡表标识内存区域的起始地址是0x0000的话,数组CARD_TABLE的第0、1、2号元素,分别对应了地址范围为0x00000x01FF、0x02000x03FF、0x0400~0x05FF的卡页内存块。

    一个卡页的内存中通常包含不止一个对象,只要卡页内有一个(或更多)对象的字段存在着跨代指针,那就将对应卡表的数组元素的值标识为1,称为这个元素变脏(Dirty),没有则标识为0。在垃圾收集发生时,只要筛选出卡表中变脏的元素,就能轻易得出哪些卡页内存块中包含跨代指针,把它们加入GCRoots中一并扫描。

    案例:CMS中的卡表。

    浅谈G1中记忆集中的实现

    使用记忆集避免全堆作为GCRoots扫描,但在G1收集器上记忆集的应用其实要复杂很多,它的每个Region都维护有自己的记忆集,这些记忆集会记录下别的Region指向自己的指针,并标记这些指针分别在哪些卡页的范围之内。G1的记忆集在存储结构的本质上是一种哈希表,Key是别的Region的起始地址,Value是一个集合,里面存储的元素是卡表的索引号。这种“双向”的卡表结构(卡表是“我指向谁”,这种结构还记录了“谁指向我”)比原来的卡表实现起来更复杂,同时由于Region数量比传统收集器的分代数量明显要多得多,因此G1收集器要比其他的传统垃圾收集器有着更高的内存占用负担。根据经验,G1至少要耗费大约相当于Java堆容量10%至20%的额外内存来维持收集器工作。

    深入理解JVM第三版,原文说的比较模糊。请注意这是在一个region维持其他region引用该region对象的信息(point out)。实际实现还是CardTable,只不过多了一个哈希表(稀疏表)。

    key为其他region的起始地址,Value为该region的卡表索引号的集合。

    展开全文
  • 记忆集和卡表

    目录

    记忆集

    记忆集有什么作用

    记忆集是什么

    记忆集的实现(卡表)

    卡表


    记忆集

    记忆集有什么作用

    这里谈记忆集,是为了解决跨代引用带来的问题。

    只针对新生代的收集(Minor GC),如果有老年代的对象引用新生的对象怎么办呢?把整个老年代检查一遍是可以,但是这样做很不值得。于是记忆集出现了。

    记忆集是什么

    记录从非收集区域指向收集区域的指针集合的抽象数据结构

    记忆集的实现(卡表)

    如上所说,记忆集是一个抽象的数据结构,需要一个对应的具体实现。

    大致思考一下,可以建立一个数组,存放所有非收集区域中有跨代引用的对象。

    虚拟机觉得这样做开销太大,没有必要。收集器只需要知道某一块非收集区域是否存在指向收集区域的指针就可以了。所以,虚拟机才用了更加粗犷的粒度,比如字长精度(一个机器字长)。

    当然对象精度也是可以,但是并不是像上边说的建立对象数组,而是存放是否有跨代指针的一个标记。

    还有就是卡精度。表示每个记录精确到一块内存区域,该区域内有对象包含跨代指针。使用卡精度实现记忆集的数据结构叫做卡表

    卡表

    在HotSpot中,卡表是一个字节数组。卡表中的每个元素对应其标识内存区域的一块特定大小的内存。这一块内存叫卡页。HotSpot的卡页是512字节。只要一个卡页中有一个对象存在跨代引用,就将对应卡表的数组元素的值标识为1,称为元素变脏。没有就为0。

    在垃圾收集时,筛选出卡表里的脏元素,把他们加入GC Roots一并扫描。

    这一篇就到这里了。

    早睡早起,注意身体。早起之王祝你一日千里

    展开全文
  • 记忆集(`remembered set`) 1.记忆集(remembered set) 问题:G1将堆区划分成多个region,一个region不可能是独立的,它其中存储的对象可能被其他任意region(这些region可能Old区或者Eden区)中的对象所引用。这样一来...

    1.记忆集(remembered set)

    问题:G1将堆区划分成多个region,一个region不可能是独立的,它其中存储的对象可能被其他任意region(这些region可能Old区或者Eden区)中的对象所引用。这样一来,在进行YGC的时候,判断Eden区中的一个对象是否存活时,需要去扫描所有的region(包括Old区,Eden区等),导致了在回收年轻代的时候,还需要扫描老年代,同时扫描表示所有Eden区和Old区的region,相当于做了一个全堆扫描,这会大大降低YGC的效率。
    为了解决上面的问题,提出了remembered set的概念。
    在这里插入图片描述
    写屏障(write barrier)

    1. 写屏障的概念比较简单,就是对一个对象引用进行写操作(即引用赋值)之前或之后附加执行的逻辑。

    写屏障与记忆集:
    每次在对一个对象引用进行赋值的时候,会产生一个写屏障中断操作,然后检查将要写入的引用指向的对象是否和该引用当前指向的对象处在不同的region中;如果不同,通过CardTable将相关的引用信息记录到Remembered set中;当进行垃圾收集时,在GC根节点的枚举范围内加入Remembered Set,就可以保证不用进行全局扫描。

    记忆集是什么?

    如下图所示,每个region都有一个记忆集(Rset),记忆集会记录下当前这个region中的对象被哪些对象所引用。例如,region2中的两个对象分别被region1中的对象和region3中的对象所引用,那么,region2的记忆集记录的就是region1region3中的引用region2的对象的引用。
    这样一来在回收region2的时候,就不用扫描全部的region了,只需要访问记忆集,就知道当前region2里面的对象被哪些对象所引用,判断其是不是存活对象。
    在这里插入图片描述
    更多JVM文章请访问我的JVM专栏:
    https://blog.csdn.net/u011069294/category_10113093.html

    展开全文
  • G1技术细节之记忆集和卡表解决跨代引用问题

    千次阅读 热门讨论 2021-02-04 10:32:24
    因此,就引入了卡表和记忆集的概念。卡表将整个老年代分成了多个层级,card[0],card[1],card[2]......。如果某个card区域中的老年代对象引用着新生代的对象,那么就被叫做脏卡。当YongGC发生时,某个新生代的对象...
  • 记忆集、卡表与写屏障

    千次阅读 2020-06-03 16:04:30
    事 实上并不只是新生代、老年代之间才有跨代引用的问题,所有涉及部分区域收集(Partial GC)行为的 垃圾收集器,典型的如G1、ZGC和Shenandoah收集器,都会面临相同的问题,因此我们有必要进一步理清记忆集的原理和...
  • HotSpot虚拟机垃圾回收细节HotSpot虚拟机垃圾回收细节一、GC Roots枚举效率的提升二、安全点和安全区策略三、记忆集和卡表五、并发可达性分析的两种避免对象消失的手段欢迎关注我、一起共勉 这部分内容略显得枯燥,...
  • 清除算法2.2 标记-复制算法2.3 标记-整理算法三、HotSpot的算法细节实现3.1 根节点枚举3.2 安全点如何在垃圾收集时让所有线程跑到最近的安全点停顿下来3.3 安全区域原理3.4 记忆集与卡表3.4.1 记忆集的实现卡表3.5 ...
  • 苹果cms dplayer播放器源码 增加记忆P2P播放 自动下一 弹幕等功能 搭建过苹果cms的都知道,苹果cms自带的播放器都特别拉跨 如:DP ali这些都只要一些基础的功能,但是现在这些功能都都满足不了用户群体,所以今天...
  • 记忆集,RemeberSet,用来记录外部指向本Region的所有引用,每个Region内都会维护一个,因此G1收集器相对而言比较消耗内存的原因就在这里,它需要约5~10%的空间维护记忆集。 卡表,CardTable,专门用来记录老年代中引用了...
  • 英语单词的构词规律也是有规可寻的。单词是由词素构成的,词素派生出词义。单词的数量虽然浩瀚,但构成其的词素的数量却是有限的。如果掌握了词素,懂得基本的构词方法,就能容易地识记单词,突破记忆单词这一难关。
  • 第三代dplayer播放器记忆+P2P播放+自动下一功能.zip播放器。
  • dplayer播放器增加记忆 P2P播放 自动下一 弹幕功能 搭建过苹果cms的都知道,苹果cms自带的播放器都特别拉跨 如:DP ali这些都只要一些基础的功能,但是现在这些功能都都满足不了用户群体,所以今天小编给大家带来...
  • 里面包含了8051单片机的主要指令方法以及记忆方法,方便嵌入式开发者使用记忆与查找。里面包含了8051单片机的主要指令方法以及记忆方法,方便嵌入式开发者使用记忆与查找。
  • Datasets:记忆数据

    2021-03-30 15:08:00
    数据 记忆数据
  • 很多影视站长都在搜索关于本地播放器实现自动播放下一的解决方案,(*-*) 我也一样!然而经过一段时间的努力在一个很给力的博客里找到了。挖出来发给各位,直接替换就OK了。记得先备份之前的,以防不兼容问题导致...
  • 再谈JVM里的记忆集合

    千次阅读 2019-10-26 19:22:13
    在HotSpot的CMS和G1垃圾收集器中,都存在记忆集合,并且其实现就是卡表,由CardTableRS类定义,是GenRemSet类的子类。之前我们已经知道,卡表是个字节数组,每个字节对应堆空间老生代中的512个字节(这512个字节...
  • 苹果CMSV10本地化CKPLAYER增加记忆播放 自动下一方法复制到苹果CMSV10的www\static\player文件夹里面!直接可以用!
  • MATLAB实现LSTM(长短期记忆神经网络)多输入单输出数据
  • 利用s-粗(singular rough sets)和S-粗的遗传特性,给出知识的f-记忆和S-粗的F。记忆的概念,利用这些概念,提出S-粗的F-记忆特性,s-粗的F记忆定理,F记忆链上知识丢失原理。F-记忆是S-粗的重要特征之...
  • 苹果cms自带的播放器都特别拉跨 如:DP ali这些都只要一些基础的功能,但是现在这些功能都都满足不了用户群体,所以今天小编给大家带来一款二改过的播放器新增了记忆播放,P2P播放,自动下一播放,弹幕功能,所以...
  • 51单片机汇编指令(附记忆方法)
  • MATLAB实现Bayes(贝叶斯)优化LSTM(长短期记忆神经网络)时间序列预测数据
  • 「纸记卡片 Paper MEMO」是一个在线工具,它可以自动生成可打印、可裁剪的记忆卡片。它能生成 A4 大小的 PDF 文件,排布一定数量的卡片:打印出来后进行裁剪,让你以“看得见摸得着”的方式使用闪记卡片。 用户只...
  • 针对目前工控网络异常流量检测方法存在识别准确率不高和识别效率低的问题,结合工控网络具有周期性的特点,提出一种基于长短期记忆网络(LSTM)的时序预测的异常流量检测模型.该模型以LSTM网络模型为核心,用前15...
  • 词根词缀记忆大全,目前最优的单词记忆方式。 通过词根词缀可以快速拓展单词记忆数量,从而提高单词量。 想要在技术学习中快速准确的阅读英文资料,词汇是重要的工具,加油吧,亲们!

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 88,401
精华内容 35,360
关键字:

记忆集