zoukankan      html  css  js  c++  java
  • C++随笔:.NET CoreCLR之GC探索(4)

      今天继续来 带大家讲解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);
    };
    

      

  • 相关阅读:
    idea高效实用快捷键【待补充】
    前台sessionStorage存取对象注意事项
    SpringBoot2.0 整合 JWT 框架后台生成token
    vue暗含玄机的v-for指令
    【串线篇】spring boot自定义starter
    【串线篇】spring boot启动配置原理
    【串线篇】spring boot整合SpringData JPA
    docker安装MySQL5.7示例!!坑,ERROR 1045 (28000): Access denied for user
    docker常用命令及操作
    docker简介及安装
  • 原文地址:https://www.cnblogs.com/kmsfan/p/5544220.html
Copyright © 2011-2022 走看看