从托管堆分配资源

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

IL指令newobj用于创建一个对象。newobj指令将导致CLR执行以下步骤:

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

2.加上对象的开销所需的字节数。每个对象都有两个开销字段:一个是类型对象指针和一个同步块索引。对于32位应用程序,这两个字段各自需要32位,所以每个对象要增加8个字节。对于64位应用程序,这两个字段各自需要64位,所以每个对象要增加16个字节。

3.CLR检查保留区域是否能够提供分配对象所需的字节数,如有必要就提交存储。如果托管堆有足够的可用空间,对象会被放入。注意对象是在NextObjPtr指针指向的地址放入的,并且为它分配的字节会被清零。接着,调用类型的实例构造器,IL指令将返回对象的地址,就在地址返回之前,NextObjPtr指针的值会加上对象占据的字节数,这样会得到一个新值,它指向下一个对象放入托管堆时的地址。

假设:地址空间和存储是无限的。

时间: 2025-01-02 02:52:15

从托管堆分配资源的相关文章

.NET 托管堆和垃圾回收

托管堆基础 简述:每个程序都要使用这样或那样的资源,包括文件.内存缓冲区.屏幕空间.网络连接.....事实上,在面向对象的环境中,每个类型都代表可供程序使用的一种资源.要使用这些资源,必须为代表资源的类型分配内存.以下是访问一个资源所需步骤:1.调用IL指令newobj,为代表资源的类型分配内存.(C# new操作符)2.初始化内存,设置资源的初始状态.(一般指构造函数)3.访问类型的成员来使用资源.(使用成员变量.方法.属性等)4.摧毁资源的状态以进行清除.(???Dispose???)5.释

.Net之托管堆资源分配

托管堆分配资源: 一:进程初始化是,CLR要保留一块联系的地址空间,这个地址空间最初并没有对应的物理存储空间.这个地址空间就是托管堆.托管堆还维护着一个指针,我把它称为NextObjPtr.它指向下个对象在堆中的分配位置.刚开始的时候NextObjPtr设为要保留地址空间的基地址. IL指令newobj用于创建一个对象: ① 计算所有类型及其所有基类型的字段需要的字节数. ② 加上对象开销所需要的字节数.每个对象都有两个开销字段,一个是类型对象指针,和一个同步快索引.对于32应用程序各自需要32

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

这里我们讨论的两个东西:托管堆和垃圾回收器,前者是负责创建对象并控制这些对象的生存周期,后者负责回收这些对象. 一.托管堆分配资源 CLR要求所有的对象都从托管堆分配.进程初始化时,CLR划出一个地址空间区域作为托管堆.CLR还要维护一个指针P,该指针指向下一个对象在堆中的分配位置. 那么我们进一步深入看看创建一个对象(也就是new 一个对象)时CLR做了哪些工作呢. 1.计算类型字段需要的字节数. 2.加上对象开销所需要的字节数,每个对象都有两个开销:类型对象指针和同步块索引 3.CLR检查区

CLR via C#-托管堆和垃圾回收

托管堆基础 访问类型的资源 面向对象的环境中,每个类型都代表可供程序使用的一种资源.要使用这些资源,必须为代表资源的类型分配内存.以下是访问一个资源所需的步骤. ①调用IL指令newobj,为代表资源的类型分配内存,由new操作符来完成. ②初始化内存,设置资源的初始状态并使资源可用,类型的实例构造器负责设置初始状态. ③访问类型的成员来使用资源. ④摧毁资源的状态以进行清理. ⑤释放内存,垃圾回收器独自负责这一步. 托管堆为开发人员提供了一个简化的编程模型,分配并初始化资源并直接使用. 大多数

重温CLR(十五) 托管堆和垃圾回收

本章要讨论托管应用程序如何构造新对象,托管堆如何控制这些对象的生存期,以及如何回收这些对象的内存.简单地说,本章要解释clr中的垃圾回收期是如何工作的,还要解释相关的性能问题.另外,本章讨论了如何设计应用程序来最有效地使用内存. 托管堆基础 每个程序都要使用这样或那样的资源,包括文件.内存缓冲区.屏幕空间.网络连接.数据库资源等.事实上,在面向对象的环境中,每个类型都代表可提供程序使用的一种资源.要使用这些资源,必须为代表资源的类型分配内存.以下是访问一个资源所需的步骤 1 调用IL指令newo

【C#进阶系列】20 托管堆和垃圾回收

托管堆基础 一般创建一个对象就是通过调用IL指令newobj分配内存,然后初始化内存,也就是实例构造器时做这个事. 然后在使用完对象后,摧毁资源的状态以进行清理,然后由垃圾回收器来释放内存. 托管堆除了能避免错误使用已经被释放的内存,也会减少内存泄漏,大多数类型都无需资源清理,垃圾回收器会自动释放资源. 当然也有需要立即清理的,比如一些包含了本机资源的类型(如文件.套接字和数据库连接等),可在这些类中调用一个Dispose方法.(当然有的类对这个方法封装了一下,可能是别的名字比如断开数据库连接的

托管堆内存分配优化

内存问题概述 和CPU一样,内存也是一个直接影响服务端性能的重要的硬件资源. 一般来说,如果服务端内存不足,从导致以下两个问题产生: 1. 导致服务端把一些原本要写到内存中的数据,写到硬盘上面.这样不仅仅加大了CPU和磁盘的I/O操作,同时也延长了读取这些数据的时间. 2. 阻止了一些缓存策略的使用. 对于内存不足,一直最快最直接的方式就是去买内存条加在服务器上面.但是这样存在一个隐患的问题就是:如果加了新的内存之后,服务端又面临内存不足的问题,我们不可能无止境的加内存条,那么我们就必须从站点本

struct对象可能分配在托管堆上吗

struct对象可能被分配在托管堆上吗? --会的. 比如当对struct装箱的时候,就会被分配在托管堆上. 比如,让一个struct实现一个接口. public interface IReport { string Name { get; } } public struct Score : IReport { public string Name { get { return "80分来自struct"; } } } 再来一个类负责打印接口属性值的类和方法. public class

堆栈和托管堆 c#

堆栈和托管堆 c# 首先堆栈和堆(托管堆)都在进程的虚拟内存中.(在32位处理器上每个进程的虚拟内存为4GB) 堆栈stack 堆栈中存储值类型. 堆栈实际上是向下填充,即由高内存地址指向低内存地址填充. 堆栈的工作方式是先分配内存的变量后释放(先进后出原则). 堆栈中的变量是从下向上释放,这样就保证了堆栈中先进后出的规则不与变量的生命周期起冲突! 堆栈的性能非常高,但是对于所有的变量来说还不太灵活,而且变量的生命周期必须嵌套. 通常我们希望使用一种方法分配内存来存储数据,并且方法退出后很长一段