一直是.NET程序员,但是.NET的核心其实还是C++,所以我准备花 一点时间来研究CoreCLR和CoreFX.希望这个系列的文章能给大家带来 帮助。

  GC的代码有很多很多,而且结构层次对于一个初学者来说,很难很快或者很慢掌握,所以我的建议是,抓住一段功能,到实际当中去看。本来想从开头 跟大家讲的,但是看 开头也是乱的,反正也没有多少经验,索性随便讲。

//返回第二个参数seg的直接前驱节点
heap_segment* heap_segment_prev (heap_segment* begin, heap_segment* seg)
{
//判断是否begin指针指向了NULL
assert (begin != 0); //定义一个局部的变量,让第一个参数begin指向这个局部的指针。
heap_segment* prev = begin; //首先得到以begin为基准的下一个堆片段的地址
heap_segment* current = heap_segment_next (begin); //循环判断“下一个”地址是不是和函数的第二个参数的地址是指向同一块内存
while (current && current != seg)
{
//把得到的current当前的地址临时指向prev
prev = current;
//去尝试得到下一个地址
current = heap_segment_next (current);
} //上一个循环结束,如果当前segment等于形参,返回上一个
if (current == seg)
{
return prev;
}
//如果当前segment是头结点,那么没有直接前驱,返回空
else
{
return 0;
}
}

  

注意这里的heap_segment是类名,定义在gcpriv.h中,heap_segment_prev是方法的名称。heap_segment,我的理解其实很简单,就是 “堆的集合”,集合当中的每个元素,就是它的一个segment,每个元素是链式连接的。

让我们来看看这个类的真容吧,这很重要,要注意它们的类型很多 都是Uint8_t,那么 这个结构体有什么特点呢?按照posix标准,一般整形对应的*_t类型为:

1字节     uint8_t
       2字节     uint16_t
       4字节     uint32_t
       8字节     uint64_t

由此我们可以得到一个很重要的信息,它们存放的片段都是 以一个字节为原子的,为什么会用这种方式去存储,这个我也不得而知。

class heap_segment
{
public:
uint8_t* allocated; //已经分配的空间
uint8_t* committed; //已经被提交的
uint8_t* reserved; //已经被存储的
uint8_t* used; //已经被使用的
uint8_t* mem; //空间
size_t flags; //标记
PTR_heap_segment next; //下一个堆的片段
uint8_t* plan_allocated; //“将要” 分配的空间
//如果BACKGROUND_GC被定义的话,执行如下代码(后台GC)
#ifdef BACKGROUND_GC
uint8_t* background_allocated; //后台分配
uint8_t* saved_bg_allocated; //已经保存的后台分配
#endif //BACKGROUND_GC //多个堆(不止是一个堆)
#ifdef MULTIPLE_HEAPS
gc_heap* heap; //这个类毕竟复杂,以后会专门抽出章节来说
#endif //MULTIPLE_HEAPS #ifdef _MSC_VER
// Disable this warning - we intentionally want __declspec(align()) to insert padding for us
#pragma warning(disable:4324) // structure was padded due to __declspec(align())
#endif
aligned_plug_and_gap padandplug;
#ifdef _MSC_VER
#pragma warning(default:4324) // structure was padded due to __declspec(align())
#endif
};

其中我来 解释一下PTR_heap_segment,它其实是一个自定义类型

typedef DPTR(class heap_segment)               PTR_heap_segment;

下面我们再回到heap_segment_prev这个方法,如果你能看懂我下面画的这幅图,你就应该能理解这个方法到底要干什么了。其实意图很明显,我们可以把heap看成是一个链表,暂时我们 不知道这个链表到底是什么链表,这个并不重要,重要的是,我们首先必须知道我们要从哪个节点开始,然后要寻找哪一个节点,就是分别对应下图的第一个参数和第二个参数,首先我们会进入一个while循环,如果我们第一次得到的不为NULL而且得到的heap的下一个节点(segment)不和第二个参数吻合,至于怎么吻合?就是2个地址是不是指指向同一块内存!直到找到为止,返回这个heap指定位置的前置节点。

  heap_segment_next 这个函数,我们看到,其实是指向heap_segment的下一个heap,并作为地址返回。

inline
PTR_heap_segment & heap_segment_next (heap_segment* inst)
{
return inst->next;
}

  下面我们再来 看一下heap_segment_in_range这个函数。我们 先看看它的定义。

inline
BOOL heap_segment_in_range_p (heap_segment* inst)
{
//它返回一个bool类型,当然此BOOL是自定义的
return (!(inst->flags & heap_segment_flags_readonly) ||
((inst->flags & heap_segment_flags_inrange) != 0));
}

  当然我们 必须知道一个基本的定义,下面变量是里面本身定义好的。

#define heap_segment_flags_readonly     1
#define heap_segment_flags_inrange 2

  由此可以推断,heap_segment_in_range_p为True.

下面我们来看这个方法,注释我已经打上了,但是我表示怀疑,为什么检测边界要通过这种一个一个链式的方式去检测,这样我们 就要把整个链表跑一次,真的有点怀疑这是不是最好的方法。

//检查堆的边界,即最后一个元素
heap_segment* heap_segment_in_range (heap_segment* ns)
{
//这里是否会执行,决定于heap_segment的一些特性(我还不知道,所以不乱说)
if ((ns == 0) || heap_segment_in_range_p (ns))
{
return ns;
}
else
{
do
{
//这段代码其实是一个循环,它的作用是检测堆的一个“右边”边界
ns = heap_segment_next (ns);
} while ((ns != 0) && !heap_segment_in_range_p (ns));
return ns;
}
}

  今天还想写的,不过很晚了,不然明天上班又起不来了。。。。先睡觉,晚安。  

C++随笔:.NET CoreCLR之GC探索(1)的更多相关文章

  1. C++随笔:.NET CoreCLR之GC探索(4)

    今天继续来 带大家讲解CoreCLR之GC,首先我们继续看这个GCSample,这篇文章是上一篇文章的继续,如果有不清楚的,还请翻到我写的上一篇随笔.下面我们继续: // Initialize fre ...

  2. C++随笔:.NET CoreCLR之GC探索(3)

    有几天没写GC相关的文章了哈,今天我讲GC的方式是通过一个小的Sample来讲解,这个小的示例代码只有全部Build成功了才会有.地址为D:\coreclr2\coreclr\bin\obj\Wind ...

  3. C++随笔:.NET CoreCLR之GC探索(2)

    首先谢谢 @dudu 和 @张善友 这2位大神能订阅我,本来在写这个系列以前,我一直对写一些核心而且底层的知识持怀疑态度,我为什么持怀疑态度呢?因为一般写高层语言的人99%都不会碰底层,其实说句实话, ...

  4. CoreCLR源码探索(五) GC内存收集器的内部实现 调试篇

    在上一篇中我分析了CoreCLR中GC的内部处理, 在这一篇我将使用LLDB实际跟踪CoreCLR中GC,关于如何使用LLDB调试CoreCLR的介绍可以看: 微软官方的文档,地址 我在第3篇中的介绍 ...

  5. CoreCLR文档翻译 - GC的设计

    此文档来源于CoreCLR的BOTR(The Book of the Runtime), 点击打开原文 一切著作权归微软公司所有 GC的设计 作者: Maoni Stephens (@maoni0) ...

  6. CoreCLR源码探索(三) GC内存分配器的内部实现

    在前一篇中我讲解了new是怎么工作的, 但是却一笔跳过了内存分配相关的部分. 在这一篇中我将详细讲解GC内存分配器的内部实现. 在看这一篇之前请必须先看完微软BOTR文档中的"Garbage ...

  7. CoreCLR源码探索(四) GC内存收集器的内部实现 分析篇

    在这篇中我将讲述GC Collector内部的实现, 这是CoreCLR中除了JIT以外最复杂部分,下面一些概念目前尚未有公开的文档和书籍讲到. 为了分析这部分我花了一个多月的时间,期间也多次向Cor ...

  8. CoreCLR源码探索(一) Object是什么

    .Net程序员们每天都在和Object在打交道 如果你问一个.Net程序员什么是Object,他可能会信誓旦旦的告诉你"Object还不简单吗,就是所有类型的基类" 这个答案是对的 ...

  9. CoreCLR源码探索(二) new是什么

    前一篇我们看到了CoreCLR中对Object的定义,这一篇我们将会看CoreCLR中对new的定义和处理 new对于.Net程序员们来说同样是耳熟能详的关键词,我们每天都会用到new,然而new究竟 ...

随机推荐

  1. Angular2入门系列教程7-HTTP(一)-使用Angular2自带的http进行网络请求

    上一篇:Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数 感觉这篇不是很好写,因为涉及到网络请求,如果采用真实的网络请求,这个例子大家拿到手估计还要自己写一个web ...

  2. Python高手之路【三】python基础之函数

    基本数据类型补充: set 是一个无序且不重复的元素集合 class set(object): """ set() -> new empty set object ...

  3. Docker笔记一:基于Docker容器构建并运行 nginx + php + mysql ( mariadb ) 服务环境

    首先为什么要自己编写Dockerfile来构建 nginx.php.mariadb这三个镜像呢?一是希望更深入了解Dockerfile的使用,也就能初步了解docker镜像是如何被构建的:二是希望将来 ...

  4. 探索ASP.NET MVC5系列之~~~4.模型篇---包含模型常用特性和过度提交防御

    其实任何资料里面的任何知识点都无所谓,都是不重要的,重要的是学习方法,自行摸索的过程(不妥之处欢迎指正) 汇总:http://www.cnblogs.com/dunitian/p/4822808.ht ...

  5. SQLSERVER聚集索引与非聚集索引的再次研究(上)

    SQLSERVER聚集索引与非聚集索引的再次研究(上) 上篇主要说聚集索引 下篇的地址:SQLSERVER聚集索引与非聚集索引的再次研究(下) 由于本人还是SQLSERVER菜鸟一枚,加上一些实验的逻 ...

  6. 这些.NET开源项目你知道吗?.NET平台开源文档与报表处理组件集合(三)

    在前2篇文章这些.NET开源项目你知道吗?让.NET开源来得更加猛烈些吧 和这些.NET开源项目你知道吗?让.NET开源来得更加猛烈些吧!(第二辑)中,大伙热情高涨.再次拿出自己的私货,在.NET平台 ...

  7. PHP中遍历XML之SimpleXML

    简单来讲述一些XML吧,XML是可扩展标记语言,是一种用于标记电子文件使其具有结构性的标记语言.XML是当今用于传输数据的两大工具之一,另外一个是json. 我们在PHP中使用XML也是用来传输数据, ...

  8. 在开启DRS的集群中修复VMware虚拟主机启动问题

    通过iSCSI方式连接到ESXi主机上的外挂存储意外失联了一段时间,导致部分虚拟主机在集群中呈现出孤立的状态,单独登陆到每台ESXi上可以看到这些虚拟主机都变成了unknow状态.因为有过上一次(VM ...

  9. 前端制作动画的几种方式(css3,js)

    制作动态的网页是是前端工程师必备的技能,很好的实现动画能够极大的提高用户体验,增强交互效果,那么动画有多少实现方式,一直对此有选择恐惧症的我就总结一下,以便在开发的时候选择最好的实现方式. 1.css ...

  10. java web学习总结(五) -------------------servlet开发(一)

    一.Servlet简介 Servlet是sun公司提供的一门用于开发动态web资源的技术. Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向 ...