CLR Via C#读书笔记——CLR分配内存【2011-01-17】

来源:互联网 发布:诺基亚c102软件下载 编辑:程序博客网 时间:2024/05/21 05:39

当应用程序的进程完成初始化后,CLR将保留一块连续的地址空间,这段空间最初并不对任何应用物理内存。该地址空间即为托管堆。托管堆上维护着一个指针,我们称之为NextObjPtr。该指针表示下一个新建对象分配时在托管堆中所处的位置。刚开始的时候,NextObjPtr被设为CLR保留地址空间的基地址。

      IL指令newobj负责创建新的对象。许多语言(C#,C++/CLI以及Microsoft Visual Basic)都提供了一个new操作符,该操作符会使编译器在相应方法的IL代码中产生一个newobj指令。在代码运行时,newobj指令将导致CLR执行以下操作:

     1.计算类型所有字段(以及其基类所有的字段)所需要的字节总数。

     2.在前面所得字节总数的基础上再加上对象开销所需的字节数。每个对象包括两个开销字段:一个是类型对象指针,另一个是同步块索引。在32位的应用程序中,这两个字段各占32位,合起来将为每个对象增加8个字节。在64位的应用程序中,两个合起来将为每个对象增加16个字节。

     3.CLR检查保留区域中的空间是否满足分配新对象所需的字节数——如果需要则提交物理内存。如果托管堆中还有足够的剩余空间,那么对象将被满足,对象将被分配在NextObjPtr指针所指是的地方,并且所分配的地址空间中的字节被清零。如果托管堆中没有足够的地址空间来分配该对象。托管堆通过将对象所需要的字节总数添加到NextObjPtr指针表示的地址上来检测这种情况。如果得到的结果超过了托管堆的地址空间范围,那么托管堆将被认为已经充满,这事就需要执行垃圾收集(我们要清楚垃圾收集只有在第0代对象充满时才会出现)。接着,类型的实例构造器被调用(NextObjPtr指针会被传递给this参数),IL指令newobj返回对象的内存地址。就在newobj指令返回对象的地址之前,NextObjPtr指针会越过对象所处的内存区域,并指示出下一个新建对象在托管堆中的地址。