.net framework中值类型和引用类型的内存分配

.net framework中值类型和引用类型的内存分配,.net,memory-management,.net,Memory Management,是否有一篇高级文章可以解释如何在.NETFramework中为不同类型(值和引用)分配内存 例如,我们知道值类型是在堆栈上分配空间的,但是如何管理它呢 另外,如何在堆中管理引用类型以及实际值存储在何处。(与任何类一样,引用类型将包含许多值类型,它们保存在何处以及如何管理)调用方法时,值类型所需的空间量是预先知道的(可以由编译器计算)。此空间在堆栈上分配,仅在方法调用期间可用。对于每个新方法调用,堆栈上使用的内存都会增加,当方法退出时,它会收缩回以前的级别 引用类型是在堆上分配的。堆基本上是用于此

是否有一篇高级文章可以解释如何在.NETFramework中为不同类型(值和引用)分配内存

例如,我们知道值类型是在堆栈上分配空间的,但是如何管理它呢


另外,如何在堆中管理引用类型以及实际值存储在何处。(与任何类一样,引用类型将包含许多值类型,它们保存在何处以及如何管理)

调用方法时,值类型所需的空间量是预先知道的(可以由编译器计算)。此空间在堆栈上分配,仅在方法调用期间可用。对于每个新方法调用,堆栈上使用的内存都会增加,当方法退出时,它会收缩回以前的级别


引用类型是在堆上分配的。堆基本上是用于此目的的内存块。存储在堆上的对象主要是存储在分配给该对象的内存中的对象字段。因此,值类型字段存储在堆上对象的“内部”。引用类型字段存储为引用对象的引用(或指针)。堆上的内存由垃圾收集管理。这是一个复杂的主题,但简短的故事是,分配给堆上未使用对象的内存会被释放,因此可以由垃圾收集器定期重复使用。

这篇文章似乎很先进,但没有过火。它应该能让您更好地理解:


这比你想象的要复杂得多。即使您声称“值类型在堆栈上分配”也不正确。例如:

class Foo
{
    int x;
}
int
是一种值类型,但x的值将始终位于堆上,因为它将与类Foo实例的其余数据一起存储

此外,为匿名函数和迭代器块捕获的变量使生活变得更加棘手

我有一本书,你可能会觉得很有用,但你也可能想读埃里克·利珀特的博客文章。特别是,未来的C#编译器可以决定将其所有局部变量存储在堆上,使用堆栈只是为了保存对在方法开始时创建的实例的引用。。。这根本不会违背C规范。

值类型是在定义的地方“分配”的

这意味着什么取决于您在哪里定义它:

  • 在类/结构中,作为该结构中的字段,放大内存中的类/结构以适应其中的值类型值
  • 作为方法中的局部变量、堆栈上的局部变量、寄存器或生成类中的字段(使用“闭包”时),具体取决于优化
  • 作为方法的参数,在堆栈上或作为寄存器,具体取决于优化
引用类型有点像双重值。引用类型本质上是指针,指针值遵循与值类型相同的“分配”规则,但一旦在其中存储了值,即对对象的引用,该对象就位于堆的其他位置

换句话说,引用变量本身是作为值类型“分配”的,但它引用的对象在堆上

从类构造对象时,会在堆上分配空间以容纳该类的所有字段+该空间中的一些开销


我似乎记得Jon Skeet有一篇关于这个主题的文章,我相信他很快就会给出答案,所以请继续关注。

记住规则,引用类型总是放在堆中,而值类型总是放在声明它们的地方。如果值类型是在方法外部声明的,但在引用类型内部声明的,则它将被放置在堆上的引用类型中。

当我键入答案时,他就在那里。