.net 从托管堆分配资源

CLR要求所有的资源都从托管堆(managed heap)分配。这个堆和c运行时堆非常相似,只是你永远不从托管堆中删除对象——应用程序不需要的对象会自动删除。这自然引起一个问题:“托管堆如何知道应用程序不再用一个对象?”我稍后就会回答这个问题。

目前使用的垃圾回收算法有好几种。每种算法都针对特定环境进行优化,能提供这种环境下最佳的性能。本章关注的是Microsoft .NET Framework 的CLR所采用的垃圾回收算法。先从最基本的概念讲起。

进程初始化,CLR要保留一块连续的地址空间,这个地址空间最初并没有对应的物理存储空间。这个地址空间就是托管堆。托管堆还维护着一个指针,我把它称为NextObjPtr. 它指向下一个对象在堆中的分配位置。刚开始的时候NextObj设为保留地址空间的基本地址。

IL指令newobj用于创建一个对象。许多语言都提供一个new操作符,它导致编译器在方法的IL代码中生成一个newobj指令。newobj指令将导致CLR执行以下步骤。
1,计算类型(及其所有基类型)的字段所需要的字节数。
2,加上对象的开销所需的字节数。每个对象都有两个开销字段:一个是类型对象指针,和一个同步块索引。对于32位应用程序,这两个字段各自需要32位,所以每个对象要增加8字节。对于64位应用程序,这每个字段各自需要64位,所以每个对象要增加16字节。
3,CLR检查保留区域是否能够提供分配对象所需的字节数,如有必要就提交存储。如果托管堆有足够的可用空间,对象会被放入。注意对象是在NextObjPtr指针指向的地址放入的,并且为它分配字段会被清零。接着,调用类型的实例构造器(为this参数传递NextObjPtr), IL指令newobj将返回对象的地址。就在地址返回之前,NextObjPtr 指针的值会加上对象占据的字节数,这样会得到一个新值,它指向下一个对象放入托管堆时的地址。

垃圾回收器的工作原理
应用程序调用new 操作符创建对象时,可能没有足够的地址空间来分配该对象。托管堆将对象需要的字节数加到NextObjPtr指针的地址上来检测这种情况。如果结果值超过了地址空间的末尾,表明托管堆已满,必须执行一次垃圾回收。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值