2010-08-01 132 views
3

这是很长的时间,因为我试图找出有关静态类的真相。我的观点是:当使用新操作符时,值类型被分配到堆栈中,堆中的引用类型。但是静态类的本质是你不能创建它的一个实例,并且确定它不是一个值类型。所以我有一个问题,在什么时候CLR为静态内容分配内存?关于什么时候......我在编译期间假设一个程序集被构建时,但我不确定。以及关于哪里...当我试图找出我阅读J.Richter的“通过C#的CLR”,并且他写道,当您创建该特定实例时,实例类的静态方法将分配在堆中类(与类型对象指针和同步块索引一起)。但我不明白。它是静态的。它不应该依赖于任何对象的状态。所以,请减轻我。静态类/成员分配在哪里?

+1

静态成员和构造函数(我相信您引用的文本引用的)和静态类之间存在差异。你知道这个区别吗?如果是这样,你具体询问哪些? – strager 2010-08-01 22:47:07

+0

好...我知道的区别不在内存分配,是吗? 在这里,我在问静态类的内存分配。我只是因为里希特书中的一个例子而引发了静态方法。但如果分配静态类和实例类的静态成员之间有任何区别,我想知道它。 – Mark 2010-08-01 23:02:34

+1

值总是在堆栈上分配的,这不是事实。当然是 – 2010-08-01 23:05:47

回答

1

除了用户堆内存之外,CLR还在堆上保存各种簿记信息&元数据。这包括你执行的方法的实际代码,以及每种加载到AppDomain中的类型的Type对象 - 它是名称,重载,是抽象的还是密封的,以及定义的所有方法的列表(包括静态和实例)方式。

当您执行一个方法时,CLR将在堆的CLR专用部分的相应Type对象中查找方法信息并执行该方法。实例和静态方法之间的唯一区别是实例方法在指向方法执行的实例的方法参数中包含额外的'this'指针。

因此,静态信息与所有其他信息一起存储在堆上,但它不与任何特定对象实例关联。

+0

是的,这很有道理!谢谢!所以,所有这些实例和静态类的东西看起来都是骗人的。它只是一个额外的“this”指针,但它们都保存在同一个地方......同样的方式。非常感谢 – Mark 2010-08-01 23:31:08

4

CLR维护与AppDomain相关的几个堆,统称为“加载堆”。它们与垃圾收集堆不同,因为它们不包含可收集对象,大多数类型相关的数据。 AppDomain生命周期中的数据类型。

静态变量的空间分配在其中的一个HighFrequencyHeap中。 JIT编译器进行分配,它直接生成的代码引用内存位置。背景信息在MSDN Magazine article