C# 托管堆和垃圾回收器GC

时间:2022-03-23 04:55:06

这里我们讨论的两个对象:托管堆和垃圾回收器,前者是卖力创建东西并控制这些东西的保留周期,后者卖力回收这些东西。

一、托管堆分配资源

CLR要求所有的东西都从托管堆分配。进程初始化时,CLR划出一个地点空间区域作为托管堆。CLR还要维护一个指针P,该指针指向下一个东西在堆中的分配位置。

那么我们进一步深入看看创建一个东西(也就是new 一个东西)时CLR做了哪些事情呢。

1、计算类型字段需要的字节数。

2、加上东西开销所需要的字节数,,每个东西都有两个开销:类型东西指针和同步块索引

3、CLR查抄区域中可用空间够不够,如果够就在指针P指向的地点放入东西。

4、挪用类型的结构器,new操纵符返回东西引用。

5、返回东西引用之前指针P会移到下个东西放入托管堆时的地点。

二、垃圾回收器回收资源

应用措施挪用new操纵符创建东西时,可能没有足够的地点空间来分配该东西,发明空间不够,CLR就执行回收.

在讲GC时我们要大白几个观点:

  根:将所有引用类型的变量都称为根

可达和不成达:至少有一个根在引用东西时我们称这个东西可达,否则我们称之为不成达。

C# 托管堆和垃圾回收器GC

正式开始垃圾回收,我们参考上面的这个图,图中A,B、C、D、E就是我们托管堆上的东西,此刻只有A和C两个东西被引用,E被C引用,法式如下:

1、CLR开始GC时,前先暂停进程中的所有线程。

2、CLR遍历堆中的所有东西,将所有东西都符号为0,暗示所有东西都应删除。

3、CLR检测所有勾当根,任何根如果引用了堆上的东西CLR就会符号阿谁东西为1.注意这里的C引用了E,在符号C的时候还要判断E是否标识了1,如果符号了就不再符号,如果没有符号则符号为1

4、符号完后堆中的东西要么是已符号1,要么是未符号0,已符号的东西为可达的,未符号的东西为不成达的,GC会接下来会删除这些未符号的东西,也就是符号为0的东西

5、GC将东西删除后进入压缩阶段,将所有东西集中在一个持续的类存中,解决了本机的空间碎片化的问题,压缩完成后,CLR恢复应用措施的所有线程。

至此,一个东西的创建到回收就完成了。