.Net7 GC标记阶段代码的改变
前言
由于业务需求,在探究.Net7的CLR,发现了一个不通的地方,也就是通过GCInfo获取到了对象之后。它并没有在GcScanRoots(对象扫描标记)里面对它进行标记,那么如果没有标记这个对象如何被计划阶段构建呢?仔细研读,发现它跟之前的代码之所以不同,是因为它把标记抽取出来,另外形成一个数组循环标记。本篇来看下。
概括
1.问题:
假如说有以下示例代码:
static void Main(string[] args)
{
Console.WriteLine("Tian Xia Feng Yun Chu Wo Bei!\r\n");
Program PM= new Program();
PM = null;
GC.Collect();
}
调用GC.Collect()函数,GC垃圾回收的第一步,就是标记。这个标记实质上可以分为以下几步。
一:获取到所有的线程(GetAllThreadList)
二:遍历循环这些线程的帧
三:通过遍历到的帧,找到这些帧对应的GCInfo
四:通过GCInfo的偏移量和寄存器找到相对应的对象
五:对找到的对象进行标记。
以上四步,基本上没变。第五步标记的时候,它加入了一些新的代码。
uint8_t *mark_queue_t::queue_mark(uint8_t *o)
{
Prefetch (o);
size_t slot_index = curr_slot_index; //这里有一个slot的索引
uint8_t* old_o = slot_table[slot_index];// 这里把这个索引的值从数组取出来
slot_table[slot_index] = o;//把新对象赋值到索引所在的数组内存
curr_slot_index = (slot_index + 1) % slot_count;
if (old_o == nullptr)//这个地方是关键,因为假如说你按照上面的示例代码,之前并没有这个PM对象。所以这个old_o是等于nullptr的,所以它直接return了。那么下面就不存在标记了。问题是这个标记不标记??还是在别的地方标记了??
return nullptr;
BOOL already_marked = marked (old_o);
if (already_marked)
{
return nullptr;
}
set_marked (old_o);
return old_o;
}
二:解决
要解决这个问题,就需要知道数组slot_table里面的数值是何时被变动的。这个其实很简单在VS里面可以,打个条件断点--值更改时中断。
结果发现在函数get_next_marked里面对slot_table数组里面的值(也就是对象)进行了一个标记
uint8_t* mark_queue_t::get_next_marked()
{
size_t slot_index = curr_slot_index; //获取到当前slot_table数组的总数索引
size_t empty_slot_count = 0;
while (empty_slot_count < slot_count) //从零开始循环总数索引
{
uint8_t* o = slot_table[slot_index]; //一个个的取出来,保存到o变量。
slot_table[slot_index] = nullptr; //然后把相应的索引位内存置0,以便下次标记的时候继续使用。
slot_index = (slot_index + 1) % slot_count;
if (o != nullptr) //如果这个o不等于null,那么下面的代码就是对它进行一个标记。
{
BOOL already_marked = marked (o); //判断它是否被标记
if (!already_marked) // 如果没有
{
set_marked (o); // 则对它进行标记
curr_slot_index = slot_index;
return o;//把标记过的对象返回
}
}
empty_slot_count++;//继续循环下一次,继续标记下一个
}
return nullptr;// 如果索引为空,则直接返回null
}
这个函数是被drain_mark_queue函数调用,而前者则是在GCScanRoot整个函数被完成之后调用的。
那么整体的就打通关节了,实质上它是抽取出来了,重新进行了标记。而非在GCScanRoot里面进行标记。
结尾:
作者:江湖评谈。公众号:jianghupt。扫码关注我,带你了解.Net高阶技术。
.Net7 GC标记阶段代码的改变的更多相关文章
- 《垃圾回收的算法与实现》——GC标记-压缩算法
基本算法 Mark-Compact与Mark-Sweep的第一阶段均为标记活跃对象,第二阶段则不同,压缩算法则是将活跃对象逻辑上移到一起. Lisp2算法 对象头中增加forwarding指针,其用法 ...
- 《垃圾回收的算法与实现》——GC标记-清除算法
基本算法 标记-清除算法由 ==标记阶段== 和 ==清除阶段== 构成. 标记即将所有活动的对象打上标记. 清除即将那些没有标记的对象进行回收. 标记与清除 遍历GC root引用,递归标记(设置对 ...
- Java GC 标记/清除算法
1) 标记/清除算法是怎么来的? 我们在程序运行期间如果想进行垃圾回收,就必须让GC线程与程序当中的线程互相配合,才能在不影响程序运行的前提下,顺利的将垃圾进行回收. 为了达到这个目的,标记/清除算法 ...
- 1. GC标记-清除算法(Mark Sweep GC)
世界上第一个GC算法,由 JohnMcCarthy 在1960年发布. 标记-清除算法由标记阶段和清除阶段构成. 标记阶段就是把所有的活动对象都做上标记的阶段. 标记阶段就是"遍历对象并标记 ...
- UIImage扩展用代码直接改变图片大小
以下内容属于转载 在iOS中,uiimage没有用于修改大小的属性,要在代码中改变uiimage图片的大小,需要扩展UIImage类,如下: 头文件: #import<UIKit/UIKit.h ...
- legend3---18、第一阶段代码完成
legend3---18.第一阶段代码完成 一.总结 一句话总结: 看起来麻烦或者自己因为厌烦不想做的,其实硬着头皮来做,一下子就做完了 1.layer_mobile的loading层和关闭loadi ...
- alpha阶段 代码结构及技术难点简介
我们的产品是安卓端app,所以目前主要就是用Android Studio来进行代码开发. Android Studio的项目的结构还是比较清晰的,如下图,主要就是java文件夹内的代码部分(.java ...
- uboot两阶段代码分析
1.启动过程特征总结(1)第一阶段为汇编阶段(start.s).第二阶段为C阶段(board.c中的start_armboot 函数)(2)第一阶段在SRAM中.第二阶段在DRAM中(3)第一阶段注重 ...
- PerfView专题 (第七篇):如何洞察触发 GC 的 C# 代码?
一:背景 上一篇我们聊到了如何用 PerfView 洞察 GC 的变化,但总感觉还缺了点什么? 对,就是要跟踪到底是什么代码触发了 GC,这对我们分析由于 GC 导致的 CPU 爆高有非常大的参考价值 ...
- RxCache 的代码分析,含缓存时间duration的在代码中改变的自己实现的机制
当应用进程创建 RxCache 的实例后,会给应用进程返回一个 rxcache实例及一个 ProxyProvider,代码如下: CacheProviders providers = new RxCa ...
随机推荐
- 可视化 之D3 与echarts 对比以及应用场景
可视化:我们想要看出一组数据的大小关系,单看数据显然不够直观.那么我们可以将它转换为一种简单易懂的图表的形式,就可以更加直观的获取数据所传递给我们的信息.这个过程就叫做数据可视化.可视化常用2个前端库 ...
- Ajax的两种写法
先写一串数据 1 { 2 "status": 200, 3 "data": { 4 "name": "web211001" ...
- 我的第一周C语言作业
这个作业属于哪个课程 https://edu.cnblogs.com/campus/zswxy/SE2020-2 这个作业要求在哪里 https://edu.cnblogs.com/campus/zs ...
- UTT艾泰路由器默认口令(admin/admin)
网络空间资产搜索: 登陆弱口令:admin/****** 登陆成功 End!!!
- 我的编程之路刷题⑦:Problem 2719.--约瑟夫问题
2719: 约瑟夫问题 时间限制 : 1.000 sec 内存限制 : 128 MB 题目描述 有M个人,其编号分别为1-M.这M个人按顺序排成一个圈.现在给定一个数N,从第一个人开始依次报数, ...
- Zabbix 监控服务介绍
Zabbix 监控服务介绍 目录 Zabbix 监控服务介绍 一.Zabbix 监控服务介绍 1.1.1 Zabbix 监控服务介绍 1.1.2 如何去做监控 1.13 硬件监控 1.1.4 系统监控 ...
- react-signature-canvas 签名功能
基于移动端需要扫码签名的功能,这里记录一下. 1.使用 react-signature-canvas 插件,npm i react-signature-canvas --save 2.此功能签名后生成 ...
- mysql datetime和timestamp区别
datetime: 保存格式为YYYYMMDDHHMMSS的整数,与时区无关,存入什么值就是什么值,不会根据当前时区进行转换.mysql5.6.4中可以存储小数片段,最多小数点后6位,在mysql5. ...
- You Don't Know JS阅读笔记
JS特性查漏补缺 [1,2,3]=="1,2,3" //true 前者会隐式转换,用逗号组合成字符串 212>'22' //true 有一个值不是number就会隐式转换成n ...
- GPS数据处理
GPS数据处理 题目内容: NMEA-0183协议是为了在不同的GPS(全球定位系统)导航设备中建立统一的BTCM(海事无线电技术委员会)标准,由美国国家海洋电子协会(NMEA-The Nationa ...