首先谢谢 @dudu 和 @张善友 这2位大神能订阅我,本来在写这个系列以前,我一直对写一些核心而且底层的知识持怀疑态度,我为什么持怀疑态度呢?因为一般写高层语言的人99%都不会碰底层,其实说句实话,我以前也不看这些东西,只是因为自己觉得对C++感兴趣,索性乱写点东西,如果有写得不好的地方,还请上面2位大神指出。

  其实我现在虽然写的是C++,但是我打算在后面把C++和.NET的一些基础类库融合起来,我发现写CLR的文章特别少,不知道什么原因。反正,废话不多,开始今天的写作吧,今天依然是把重点集中在GC上面。

  首先跟大家分享一下我这次碰到的一个有趣的东西,就是下面的东西,下面的东西我第一次看,不过我可以确定的是,GC的运行模式有以下。以下都有注释,我就不详解了,不过跟大家说一下我的一个小小的发现:我猜测,以下代码只在64位GC下运行,这句话听起来很拗口,但是我是怎么得到这个结论的呢?

// !!!!!!!!!!!!!!!!!!!!!!!
// make sure you change the def in bcl\system\gc.cs
// if you change this!
//上面那句ENGLISH的意思就是如果要改这里面的值,必须先改变bc1\system\gc.cs里面的定义
//收集器运行模式
enum collection_mode
{
collection_non_blocking = 0x00000001, //非锁定模式
collection_blocking = 0x00000002, //锁定模式
collection_optimized = 0x00000004, //优化模式
collection_compacting = 0x00000008 //最小适配模式 #ifdef STRESS_HEAP //如果定义了Stress_heap,我这里翻译为压力堆,也就是“入堆”
, collection_gcstress = 0x80000000 //这里我觉得应该是GC可以入堆的一个条件吧,虽然我不懂这个是什么意思
#endif // STRESS_HEAP
};

  

  虽然我不敢完全说我是对的,但是有一点可以确定,就是它会生成x64,以windows内核为寄托的一个以i结尾的文件,我们可以把它理解为一个临时文件,而GC和windows内存的关系就像一个寄宿关系一样,GC是依赖于windows内核的某个东西生存(全是个人的猜测)。

  那么,这些enmu类型的固定值,在GC当中,到底起了一个什么样的作用呢?我随便找了几个变量,因为这些固定值,其实在GC当中,你可以理解它是无处不在的,就相当于平常写代码的if else 一样普通,大家知道这些变量的用处就行了,不必过于纠结代码是什么意思,因为以后我会带大家慢慢研究。

//如果定义成了后台GC
#ifdef BACKGROUND_GC
if (recursive_gc_sync::background_running_p())
{
//如果mode(暂时可以理解为一个变量)
//collection_non_blocking 值是0x00000001,也就是说mode&collection_non_blocking其实只要比较最右边一位就OK了,也就是mode=1 or 4
if ((mode == collection_optimized) || (mode & collection_non_blocking))
{
return S_OK;
}
if (mode & collection_blocking)
{
pGenGCHeap->background_gc_wait();
if (mode & collection_optimized)
{
return S_OK;
}
}
}

  今天我也不想过多的浪费时间,我打算挑一个有代表性的代码片段来带大家了解GC,所谓GC,GC是什么,那么它肯定有一个Collect的方法;好,那我们就拿这个方法开刀吧。首先我们必须知道几个知识点,对于非c++程序员来说,也还是需要学一点东西,size_t的解释,在这里简单一点说就是long unsigned  int ,我为什么特意把long标红呢?因为我们的GC使用的方法,是在64位环境下运行的,如果是32位的,那么就是unsigned int .

  因为这段代码很长,所以我打算:先讲一部分,然后再讲剩下的部分,不然大家就算看注释,也会眼花的。

//函数返回值。如果这个函数是执行完返回的话将包含具有实际意义的数据,如果立即返回则包含状态信息--发送成功与否 -来自百度
HRESULT //generation(代,比如你和你父母是2代人)
//
GCHeap::GarbageCollect (int generation, BOOL low_memory_p, int mode)
{
//如果定义了64位的。。。也就是说,此GC的CLR是在64位运行时上跑的
#if defined(BIT64) //如果定义了弱存储指针 PS:我也不知道怎么翻译,索性把low翻译成弱。
if (low_memory_p)
{
//1.初始化:所有已经分配的空间
size_t total_allocated = 0;
//所有“想要”分配的空间
size_t total_desired = 0; //如果定义了复杂堆(我自己翻译的)
#ifdef MULTIPLE_HEAPS
int hn = 0; //n_heaps这个定义我没找到,不过我可以确定的是,这个肯定是和MULTIPLE_HEAPS有关的
//大家可以把这个理解为MULTIPLE_HEAPS.Length
for (hn = 0; hn < gc_heap::n_heaps; hn++)
{
//首先是定义一个“临时”的指针hp,让gc堆当中的每一项都指向这个变量。
gc_heap* hp = gc_heap::g_heaps [hn]; //把每一块想要分配的数量,叠加起来。
total_desired += dd_desired_allocation (hp->dynamic_data_of (0)); //总分配量=想要分配的-新分配的
total_allocated += dd_desired_allocation (hp->dynamic_data_of (0))-
dd_new_allocation (hp->dynamic_data_of (0));
}

  大家需要从上面的代码当中,掌握如下几个基础知识点:

  一个是dynamic_data_of方法,它返回了一个dynamic_data类的指针变量,那我们乘胜追击,看看这个方法和类。

    PER_HEAP
dynamic_data* dynamic_data_of (int gen_number);

  首先是方法:

//返回dynamic_data_table的第一个Table,大家可以类比.net中的DataSet
inline
dynamic_data* gc_heap::dynamic_data_of (int gen_number)
{
return &dynamic_data_table [ gen_number ];
}

  然后我们再来看看这个dynamic_data_table,

    PER_HEAP
dynamic_data dynamic_data_table [NUMBERGENERATIONS+1];

  下面来看这张图,突然我恍然大悟,所谓的DataTable,就是我们每次使用的DataSet,其实底层是放在堆栈上面的,以复杂堆的方式存放,而每个DataTable,其实就是堆栈当中的小小的组成而已,不止我理解得对不对。

其中上面代码中的下面2个方法,都是和dynamic_data有关系的。其中ptrdiff_t类型变量通常用来保存两个指针减法操作的结果,这也是需要.NET程序员注意的,毕竟搞.NET是不和指针打交道的。

inline
size_t& dd_desired_allocation (dynamic_data* inst)
{
return inst->desired_allocation;
}
inline
ptrdiff_t& dd_new_allocation (dynamic_data* inst)
{
return inst->new_allocation;
}

  大家还要注意一下小细节,就是+=其实是先+=,再减去新分配的空间。

  今天就说这么多了,因为我还要做其他的事情,最后跟大家卖个关子,那些说.NET没技术含量的人,其实是不了解.NET原理的人。下面的就是一个比较复杂的类,这里面定义了超多的友元类,也就是说,GC表面上是一段代码,其实这就是一部重型航空母舰,需要我们去探索它的结构。

  爱因斯坦曾经说过一句名言:追求真理比占有真理更可贵。我们要做的,不仅仅是一颗螺丝钉。

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

  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探索(1)

    一直是.NET程序员,但是.NET的核心其实还是C++,所以我准备花 一点时间来研究CoreCLR和CoreFX.希望这个系列的文章能给大家带来 帮助. GC的代码有很多很多,而且结构层次对于一个初学 ...

  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. 恢复SQL Server被误删除的数据

    恢复SQL Server被误删除的数据 <恢复SQL Server被误删除的数据(再扩展)> 地址:http://www.cnblogs.com/lyhabc/p/4620764.html ...

  2. ASP.NET Aries 入门开发教程9:业务表单的开发

    前言: 经过前面那么多篇的列表的介绍,终于到了大伙期待的表单开发了. 也是本系列的最后一篇文章了! 1:表单页面的权限设置与继承 对于表单页面,权限的设置有两种: 1:你可以选择添加菜单(设置为不显示 ...

  3. xamarin DependencyService源码阅读

    xamarin在面对PCL无法实现的各平台特有功能时使用了一种叫[DependencyService]的方式来实现.它使得xamarin能像原生平台一样做平台能做到的事情!主要分四个部分 接口:定义功 ...

  4. HTML5 input元素新的特性

    在HTML5中,<input>元素增加了许多新的属性.方法及控件.本文章分别对这三方面进行介绍. 目录 1. 属性 2. 方法 3. 新控件 1. 属性 <input>元素在H ...

  5. 前端学HTTP之实体和编码

    前面的话 每天都有各种媒体对象经由HTTP传送,如图像.文本.影片以及软件程序等.HTTP要确保它的报文被正确传送,识别.提取以及适当处理.为了实现这些目标,HTTP使用了完善的标签来描述承载内容的实 ...

  6. nodejs模块发布及命令行程序开发

    前置技能 npm工具为nodejs提供了一个模块和管理程序模块依赖的机制,当我们希望把模块贡献出去给他人使用时,可以把我们的程序发布到npm提供的公共仓库中,为了方便模块的管理,npm规定要使用一个叫 ...

  7. Android Notification 详解(一)——基本操作

    Android Notification 详解(一)--基本操作 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Notification 文中如有纰 ...

  8. 使用po模式读取豆瓣读书最受关注的书籍,取出标题、评分、评论、题材 按评分从小到大排序并输出到txt文件中

    #coding=utf-8from time import sleepimport unittestfrom selenium import webdriverfrom selenium.webdri ...

  9. Java 程序优化 (读书笔记)

    --From : JAVA程序性能优化 (葛一鸣,清华大学出版社,2012/10第一版) 1. java性能调优概述 1.1 性能概述 程序性能: 执行速度,内存分配,启动时间, 负载承受能力. 性能 ...

  10. Ubuntu安装redis并配置远程、密码以及开启php扩展

    一.前言 redis是当前流行的nosql数据库,很多网站都用它来做缓存,今天我们来安装并配置下redis 二.安装并配置redis 1.安装redis sudo apt-get install re ...