• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

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

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

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

一、托管堆分配资源

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

   那么我们进一步深入看看创建一个对象(也就是new 一个对象)时CLR做了哪些工作呢。

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

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

   3、CLR检查区域中可用空间够不够,如果够就在指针P指向的地址放入对象。

   4、调用类型的构造器,new操作符返回对象引用。

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

二、垃圾回收器回收资源

    应用程序调用new操作符创建对象时,可能没有足够的地址空间来分配该对象,发现空间不够,CLR就执行回收.

    在讲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恢复应用程序的所有线程。

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

   

   


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
C#基础系列-dynamic发布时间:2022-07-14
下一篇:
[c#]RabbitMQ的简单使用发布时间:2022-07-14
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap