简单介绍 g1gc Snapshot-At-The-Beginning与Remembered Sets
Snapshot-At-The-Beginning
标记方式有两种方式
- 增量更新(Increment Update)
- 初始快照( Snapshot At The Beginning SATB)
SATB( Snapshot At The Beginning, 初始快照) 是一种将并发标记阶段开始时对象间的引用关系, 以逻辑快照的形式进行保存的手段
介绍并发标记
介绍简单标记
- 在简单标记中, 所有可从根直接触达的对象都会被添加标记。 带标记的是存活对象, 不带标记的是死亡对象
- 在简单标记中, 所有可从根直接触达的对象都会被添加标记。 带标记的是存活对象, 不带标记的是死亡对象
标记位图
将用于标记的比特值等信息单独拿出来放到其他地方, 用来匹配对应的对象。
- bottom 表示区域内众多对象的末尾
- nextTAMS 中的 TAMS 是“Top At Marking Start”(标记开始时的 top) 的缩写
- nextTAMS 保存了本次标记开始时的 top, 而 prevTAMS 保存了上次标记开始时的 top。
- next 是本次标记的标 记位图
- prev 是上次标记的标记位图, 保存了上次标记的结果
流程
初始标记阶段
- GC 线程首先会创建标记位图 next
- nextTAMS 指的 就是标记开始时 top 所在的位置, 所以在这里我们将它和 top 对齐
并发标记阶段
概念:在并发标记阶段, GC 线程继续扫描在初始标记阶段被标记过的对象, 完成对大部分存活对象的标记
这个阶段是与用户线程并发执行的,那怎么来标记呢
首先根据快照,来标记各个引用。
new 新对象
对象成员变量的变化
记录引用关系,所以需要写屏障技术,称之为 SATB 专用写屏障。
伪代码
1: def satb_write_barrier(field, newobj):2: if $gc_phase == GC_CONCURRENT_MARK:3: oldobj = *field // (a)4: if oldobj != Null:5: enqueue($current_thread.stab_local_queue, oldobj) // (b)6:7: *field = newobj // (c)
加入队列后的处理
- 只扫描未被标记的
- 已经标记的不处理
并发标记阶段结束后区域的状态
疑问
- 多线程环境下如何加入队列
- 由GC线程来处理
- 绑定线程队列
- 线程本地队列满了,再放入全局队列
- 并发写一个字段,如果obj3对象field引用了objo, 两个线程并发赋值obj1,obj2. 导致obj1没有加入队列,那obj1会丢失吗
obj1有两种可能,一种是new的,一种是另一个引用。
obj1 未被 SATB 专用写屏障获知时对象之间的关系
那obj4移除对obj1的引用会有问题吗
- 多线程环境下如何加入队列
最终标记阶段
- 未装满的 SATB 本地队列
存活对象计数
- 这个步骤会扫描各个区域的标记位图 next, 统计区域内存活对象的字节数
收尾工作
- next_marked_bytes 替换为prev_marked_bytes,同时, prevTAMS 被移到了 nextTAMS 先前的位置
- 总的流程图
remembered set
- SATB 队列集合主要用 来记录标记过程中对象之间引用关系的变化
- 转移专用记忆集合则用
来记录区域之间的引用关系。 通过使用转移专用记忆集合, 在转移时即
使不扫描所有区域内的对象, 也可以查到待转移对象所在区域内的对象
被其他区域引用的情况, 从而简化单个区域的转移处理 - 那为什么要使用remembered set,什么情况下使用
减少全扫描
分代垃圾回收,之间是怎么引用的
- 分区内部引用
- 无论是新生代还是老年代的分区内部的引用,都不需要记录引用关系。因为是针对一个分区进行的垃圾回收,要么这个分区被回收,要么不被回收。
- 年轻代与年轻代之间的引用
- G1 的三种回收算法(YGC/MIXED GC/FULL GC)都会全量处理新生代分区,所以新生代都会被遍历到。因此无需记录这种引用关系。
- 年轻代引用年老代
- 无需记录。G1 的 YGC 回收新生代,无需这个引用关系。混合 GC 时,G1 会采用新生代分区作为根,那么在遍历新生代分区时就能找到老年代分区了,无需这个引用关系。对于 FGC 来说,所有分区都会被处理,也无需这个引用关系。
- 年老代引用年轻代
- 需要记录。YGC 在回收新生代时,如果新生代的对象被老年代引用,那么需要标记为存活对象。即此时的根对象有两种,一个是栈空间 / 全局变量的引用,一个是老年代到新生代的引用。
- 年老代引用年老代
- 需要记录。混合 GC 时,只会回收部分老年代,被回收的老年代需要正确的标记哪些对象存活。
- 分区内部引用
记录引用方式
- point -in
- point-out
如何记录引用关系
- 对象与对象的引用
- region 与 region
- 对象与region
- region 与 卡表(Card Table)
Card Table
卡表是由元素大小为 1 B 的数组实现的(图 3.3) 。 卡表里的元素称为卡片
卡表的实体是数组。 数组的元素是 1 B 的卡片, 对应了堆中的 512 B。 脏卡片用灰色表示, 净卡
片用白色表示根据对象获取对应的卡表
- 卡表的实体是数组。 数组的元素是 1 B 的卡片, 对应了堆中的 512 B。
- (对象的地址 - 堆的头部地址)/ 512
因为卡片的大小是 1 B, 所以可以用来表示很多状态。 卡片的种类很多, 我们主要关注以下两种
- 净卡片
- 净卡片
记忆集合的构造
- 每个区域中都有一个转移专用记忆集合, 它是通过散列表实现的。 散列
表的键是引用本区域的其他区域的地址, 而散列表的值是一个数组, 数
组的元素是引用方的对象所对应的卡片索引。
- 每个区域中都有一个转移专用记忆集合, 它是通过散列表实现的。 散列
写屏障
当对象的域被修改时, 被修改对象所对应的卡片会被转移专用写屏障记
录到转移专用记忆集合中。 转移专用写屏障的伪代码如代码清单多线程优化
记忆集合维护线程
- 转移专用记忆集合维护线程主要进行下列处理
- 从转移专用记忆集合日志的集合中取出转移专用记忆集合日志, 从
头开始扫描 - 将卡片变为净卡片
- 检查卡片所对应存储空间内所有对象的域
- 往域中地址所指向的区域的记忆集合中添加卡片
- 从转移专用记忆集合日志的集合中取出转移专用记忆集合日志, 从
- 转移专用记忆集合维护线程主要进行下列处理
热卡片
- 频繁发生修改的存储空间所对应的卡片称为热卡片(hot card)
- 热卡
片可能会多次被转移专用记忆集合维护线程处理成脏卡片, 从而加重转
移专用记忆集合维护线程的负担, 因此需要特别处理。 - 卡片计数表,它记录了卡片变成脏卡片的次
数。 - 脏卡片阈值(默认是 4)
那GC时,记忆集合如何转移呢
转移对象
- 是指参考并发标记提供的信息来选择被转移的区域。 被选中的区域称
为回收集合 - 是指将回收集合内由根直接引用的对象, 以及被其他区域引用的对象
转移到空闲区域中。 - 是指以②中转移的对象为起点扫描其子孙对象, 将所有存活对象一并
转移。 当③结束之后, 回收集合内的所有存活对象就转移完成了。 - 伪代码
简单介绍 g1gc Snapshot-At-The-Beginning与Remembered Sets相关推荐
- Oracle10g SQL tune adviser简单介绍【转自ITPUB zhouwf0726】
Oracle10g SQL tune adviser Oracle10g SQL tune adviser简单介绍 本文简单介绍下SQL Tuning Adviser的配置使用方法和一些相关知识点,如 ...
- python测试驱动开发_使用Python进行测试驱动开发的简单介绍
python测试驱动开发 by Dmitry Rastorguev 德米特里·拉斯托格夫(Dmitry Rastorguev) 使用Python进行测试驱动开发的简单介绍 (A simple intr ...
- Springboot简单介绍
Springboot入门介绍 一.Spring框架概述 1.1 什么是Spring Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnso ...
- Snowflake 简单介绍与使用
目录 Snowflake 入门 1. Snowflake 简介 multi-cluster & shared-data 三层架构 数据存储层(Database Storage) 虚拟仓库层(V ...
- 1、hadoop3.1.4简单介绍及部署、简单验证
Hadoop系列文章目录 1.hadoop3.1.4简单介绍及部署.简单验证 2.HDFS操作 - shell客户端 3.HDFS的使用(读写.上传.下载.遍历.查找文件.整个目录拷贝.只拷贝文件.列 ...
- 遗传算法的简单介绍以及模式定理的简单证明
遗传算法 遗传算法(Genetic Algorithm,GA),最早是由美国的John holland在20世纪70年代提出.算法通过模拟达尔文生物进化论的自然选择以及遗传学机理的生物进化过程来搜 ...
- 2021年大数据ELK(十八):Beats 简单介绍和FileBeat工作原理
全网最详细的大数据ELK文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 Beats 简单介绍和FileBeat工作原理 一.Beats 二.FileB ...
- 2021年大数据ELK(十五):Elasticsearch SQL简单介绍
全网最详细的大数据ELK文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 Elasticsearch SQL简单介绍 一.SQL与Elasticsear ...
- 2021年大数据ELK(二):Elasticsearch简单介绍
全网最详细的大数据ELK文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 系列历史文章 一.Elasticsearch简介 1.介绍 2.创始人 二.E ...
最新文章
- Python3中的装饰器
- 判断浮点数溢出的方法
- python 必备模块和包_Python_异常和模块
- 自定义Excel下拉菜单
- XCTF-MISC-新手区-掀桌子
- 数学家比10个师更有威力?
- 关于Git和Github
- 计算机算法对程序设计的作用,算法计算机论文,关于数学算法对计算机编程优化相关参考文献资料-免费论文范文...
- 在Windows平台下实现《简明 Python 教程》第十章案例(利用winrar实现压缩备份)...
- 在web项目启动时,使用监听器来执行某个方法
- 学会人工智能可以从事哪些行业?
- 数据科学 | Pandas新手入门
- 太空帝国5(Space Empires V SE5)攻略
- 洗内衣、白鞋、羊毛衫……需要专用清洁剂吗
- Several ports (8005, 8080, 8009) required by demo are already in use. The server may already be runn
- TFN系列FB18电缆故障测试仪-电力电网系统首选产品
- 管理好你的20~30岁
- java判断全角_Javascript判断日文全角半角长度
- Macbook Pro上手手札
- 分析大量壹米滴答物流揽收后是否有物流的实例步骤