当我们进行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收集器的工作。

JVM之记忆集和卡表相关推荐

  1. JVM之记忆集|卡表|写屏障

    背景 分代收集理论的时候,会存在为了解决对象跨代引用所带来的的问题.垃圾收集器在新生代中建立了名为记忆集的数据结构,用来避免把整个老年代加进GC roots扫描范围.事 实上并不只是新生代.老年代之间 ...

  2. G1技术细节之记忆集和卡表解决跨代引用问题

    跨代引用面临的问题 首先,产生跨代引用场景是发生YongGC的过程.此时新生代的对象会开始寻找根,看自己是否属于根可达对象,从而判断自己是否是垃圾. 那很多同学就开始有疑惑了?不是判断对象是否存活,应 ...

  3. JVM垃圾回收-记忆集和卡表

  4. Hotspot细节实现安全区域、记忆集卡表

    Hotspot细节实现 文章目录 Hotspot细节实现 3.安全区域 产生原因 安全区域概念 实现过程 4.记忆集与卡表 产生原因: 记忆集概念 实现过程: 卡精度(卡表) 3.安全区域 产生原因 ...

  5. JVM---G1中的RSet和卡表

    关于跨代引用和YGC什么的我就解释了,如果描述清楚的话,又要写一大篇,况且网上关于这些概念的解释有很多,我这里只说一下几个我理解错和理解好长时间的地方. 参考文章 <JVM(十二)记忆集和卡表& ...

  6. 记忆集(Remember Set)和卡表(Card Table)

    记忆集和卡表 为了解决对象跨代引用所带来的问题,垃圾收集器在新生代中建立了名为记忆集(Remembered Set)的数据结构,用以避免把整个老年代加进GC Roots扫描范围.事实上并不是只是新生代 ...

  7. java 卡表_jvm-卡表,垃圾回收时的重要手段

    背景 最近在跟同事进行jvm垃圾回收的交流,讨论到通过GC Roots进行对象的可达性分析,标记存活对象的时候,同事提出了一个疑问,因为年轻代中发生minor gc的频率很高,如果在经常会扫描年轻代中 ...

  8. jvm根节点枚举、安全点、安全区域、记忆集、卡表、写屏障、并发的可达性分析

    讲具体的实现之前,先说说几个和这些垃圾回收器息息相关的一些知识点,可以有一个更好的理解 1.根节点枚举 也就是可达性分析算法从GC Roots集合中找引用链的过程,可作为GC Roots的节点主要在全 ...

  9. JVM(3)之垃圾回收(GC垃圾收集器+垃圾回收算法+安全点+记忆集与卡表+并发可达性分析......)

    <深入理解java虚拟机>+宋红康老师+阳哥大厂面试题2总结整理 一.堆的结构组成 堆位于运行时数据区中是线程共享的.一个进程对应一个jvm实例.一个jvm实例对应一个运行时数据区.一个运 ...

最新文章

  1. 一些惹起热烈争议的PCB布线经验法则
  2. Windows 8 :妥协的产物
  3. CSS布局——display,position,float属性
  4. css overflow属性的测试
  5. 通过程序实现文件下载更名,动态文件下载
  6. 一起谈.NET技术,在ASP.NET MVC3 中利用JSONP跨域登录WEB系统
  7. 推荐21个顶级的Vue UI库!
  8. 日期相关的小函数汇总
  9. 【Unity UGUI】屏幕坐标转换
  10. 工业企业成本费用的核算方法
  11. 饭店点餐系统之模块划分
  12. win7怎么修改系统语言
  13. 主宰互联网的超强10大算法!
  14. 云计算中心怎么选址?
  15. R语言double数据转成numeric类型
  16. 计算机系统盘涨满怎么办,电脑重装系统后C盘爆满?教你一招让空间大幅释放!-电脑c盘满了怎么办...
  17. oul可以用作c语言常量吗,电子科大16秋《C语言(专科)》在线作业3答案
  18. 功利性地去多读书 (现实版)
  19. openwrt 单独编译某个模块
  20. hibernate 根据方言生成sql

热门文章

  1. CVPR 2017:Interspeices Knowledge Transfer for Facial KeyPoint Detection(跨物种脸部关键点检测知识迁移)
  2. 传美云商系统开发源码
  3. 关于virtualbox虚拟电脑控制台严重错误解决方法。。。(博客园搬家至此,尚未整理)(六)
  4. 09组-选题与需求分析报告
  5. Unity VR开发教程 OpenXR+XR Interaction Toolkit (二) 手部动画
  6. 太秀了!用Pandas秒秒钟搞定24张Excel报表,还做了波投放分析!
  7. dell Precision 3550 更换固态硬盘
  8. Python安装Pyecharts和Jupyter Notebook,与使用
  9. android 耳机检测,android 检测耳机是否插入方法
  10. 20175208 实验一 Java开发环境的熟悉