杉木的园子

CLR托管堆分配资源与垃圾回收

一、托管资源分配

CLR要求所有的资源都要从托管堆中分配。进程初始化的时候,CLR会划出一个地址空间区域专门做为托管堆。CLR也会维护一个指针,暂且称为NextObjPtr。这个指针表示堆上下一个分配空间的对象。

C# new操作符导致CLR执行以下步骤:

  1. 计算类型字段所需要的字节数(包括从父类继承的所有字段)
  2. 加上对象开销所需要的字节数。每个对象都有两个开销字段:一个对象指针和一个同步块索引。对于32位应用,每个字段需32 bits,也就是需要增加8 bytes。对于64位应用,每个字段就是64 bit,对应每个对象就是要增加16 bytes。
  3. CLR然后检查在这块空间区域中分配资源所需要的的字节数是否够用。如果空闲空间足够,对象就会分配到NextObjPtr指针指向的地址,上面计算的字节数也就会被清零。类型的构造函数被调用,通过new字符返回对象的引用。在对象引用返回前,NextObjPtr已经      指向下一个需要放在在堆上对象的地址。 

二、垃圾回收

CLR垃圾回收采用的是引用跟踪算法。

CLR启动垃圾回收(GC),首先会暂停进程内的所有线程,这是为了防止CLR在检查对象的过程中,其他线程访问对象从而改变对象状态。然后开始GC标记阶段。

首先,它遍历堆中的所有对象,设置位(包含在同步块索引字段中)为0,也就是说所有对象都是需要删除的状态。,然后CLR会查看所活动跟引用,看他们指向哪些对象。对于对象为空的,直接忽略掉,不为空的则标记为1。当对象被标记时,CLR会检查对象内部的跟引用,找到他们指向的对象,然后进行标记。对于已经标记过的对象,则不重复查找内部引用,防止死循环。

 

posted @ 2022-05-09 00:39  杉木2019  阅读(50)  评论(0编辑  收藏  举报