今天继续来 带大家讲解CoreCLR之GC,首先我们继续看这个GCSample,这篇文章是上一篇文章的继续,如果有不清楚的,还请翻到我写的上一篇随笔。下面我们继续:
// Initialize free object methodtable. The GC uses a special array-like methodtable as placeholder
// for collected free space.
//
//初始化释放器(对象方法表),<-不知道翻译得对不对。
//GC使用一个很特别的像数组的methodtable作为占位符收集空闲空间
static MethodTable freeObjectMT;
那么这个MethodTable到底是“何方神圣”呢?下面只列出了部分的方法;
class MethodTable
{
public:
uint16_t m_componentSize; //容器大小
uint16_t m_flags; //标识符
uint32_t m_baseSize; //初始(最小大小,反正我是这么理解的)
MethodTable * m_pRelatedType; //关联类型,是一个MethodTable类型的指针
public:
void InitializeFreeObject() //初始化“空闲”对象
{
//void(*)科普↓↓↓↓
//http://www.zhihu.com/question/24398191?sort=created
m_baseSize = 3 * sizeof(void *);
m_componentSize = 1;
m_flags = 0;
}
uint32_t GetBaseSize()
{
return m_baseSize;
}
uint16_t RawGetComponentSize()
{
return m_componentSize;
}
}
下面我们再回到GCSample.cpp文件,其中得到的初始化的空间赋给了一个叫做g_pFreeObjectMethodTable的指针,这是为什么呢?
//初始化
freeObjectMT.InitializeFreeObject();
//不知道为什么要赋给它
g_pFreeObjectMethodTable = &freeObjectMT;
下面来看一下这个方法,我并不知道它说的handle table是何物,所以这里还需要继续探索。
// 初始化handle表(“引用”是否初始化)
if (!Ref_Initialize())
return -1;
我们来看看Ref_Initialize()这个方法,我打算一步步分解这个方法,我们首先注意到CONTRACTL和 CONTRACTL_END,这2个宏其实是定义在gcenv.base.h中的,也就是说,从这个定义当中,我们获取到了一个有用的信息:它是GC环境变量的一部分,在不同的CPU或者系统的机器上,我敢大胆的预测,他们都会从dynamic->具体的值。
//协议开始(暂时都这么说,只是猜测)
CONTRACTL
{
NOTHROW;//同 NO - THROW
WRAPPER(GC_NOTRIGGER); //同 NO -TRIGGER
INJECT_FAULT(return false); //如果注入失败,那么直接返回FALSE
}
CONTRACTL_END; //协议结束
我们再来看如下的代码,是不是有种无从下手的感觉?那么我就带你来进行一番解析吧。
// sanity
_ASSERTE(g_HandleTableMap.pBuckets == NULL);
从下图当中,完全已经详细的标注了编译器寻找代码的过程,关于assert的一些文字,大家可以自行百度。
关于g_HandleTableMap,由于篇幅和时间有限,我这里只讲一下和g_HandleTableMap.pBuckets有关的代码,余下的,如果各位有兴趣的,可以自己研究 ~下面图中显示了pBuckets的真容。
其实可以这么说,它的内部是一个HandleTableBucket,下面是它的代码,当然我我没有讲全,而且,我的外语水平很烂,将就看吧。
// struct containing g_SystemInfo.dwNumberOfProcessors HHANDLETABLEs and current table index
// instead of just single HHANDLETABLE for on-fly balancing while adding handles on multiproc machines
//结构体包含了gc系统信息dw进程(PTR_HHANDLETABLE),以及当前table的下标
//这里要说起来很复杂,反正简单点理解,就是一个Dataset,懂了吧;
struct HandleTableBucket
{
PTR_HHANDLETABLE pTable;
uint32_t HandleTableIndex;
bool Contains(OBJECTHANDLE handle);
};