是否有一篇我可以阅读的高级文章可以解释如何在.net框架中为不同类型(值和引用)分配内存。
例如,我们知道值类型在堆栈上分配了空间,但是如何管理?
如何在堆中管理引用类型以及存储实际值的位置。 (类似于任何类的引用类型将包含许多值类型,它们保存在何处以及如何管理)
答案 0 :(得分:10)
这比你想象的要复杂得多。甚至你声称“值类型在堆栈上分配”也是不正确的。例如:
class Foo
{
int x;
}
int
是一个值类型,但x的值总是在堆上,因为它将与Foo实例的其余数据一起存储,这是一个类。
此外,匿名函数和迭代器块的捕获变量使生活变得更加棘手。
我有一个article about C# heap/stack memory您可能会觉得有用,但您可能还想阅读Eric Lippert在"The stack is an implementation detail"上的博客文章。特别是,未来的C#编译器可以决定将所有局部变量存储在堆上,使用堆栈只是为了保存对在方法开始时创建的实例的引用...这不会违反C#规范所有
答案 1 :(得分:3)
值类型在已定义的位置“已分配”。
这意味着什么取决于你定义它的位置:
引用类型是双重值。引用类型的核心是指针,指针值遵循与“分配”相同的规则作为值类型,但是一旦在其中存储了值,即。对象的引用,该对象在其他地方的堆上。
换句话说,引用变量本身被“分配”为值类型,但它引用的对象在堆上。
当您从类构造对象时,会在堆上分配空间以适合该类的所有字段+该空间中的一些开销。
我似乎记得Jon Skeet有一篇关于这个主题的文章,我相信他很快就能得到答案,所以请继续关注。
答案 2 :(得分:2)
这篇文章看起来很先进而不会过分。它应该为您提供更好的理解:
http://www.simple-talk.com/dotnet/.net-framework/understanding-garbage-collection-in-.net/
答案 3 :(得分:2)
记住规则,引用类型总是转到堆,而值类型总是转到它们声明的位置。如果在方法之外声明了Value Type,但在Reference Type中,它将被放置在堆上的Reference Type中。
答案 4 :(得分:1)
当调用方法时,值类型所需的空间量是预先知道的(它可以由编译器计算)。此空间在堆栈上分配,仅在方法调用期间可用。对于每个新方法调用,堆栈上使用的内存都会增长,当方法退出时,它会收缩回到之前的级别。
引用类型在堆上分配。堆基本上是用于此目的的内存块。存储在堆上的对象主要是存储在分配给对象的内存中的对象的字段。因此,值类型字段存储在堆上的对象“内部”。引用类型字段存储为引用对象的引用(或指针)。堆上的内存由垃圾回收管理。这是一个复杂的主题,但短篇小说是分配给堆上未使用的对象的内存被释放,因此可以由垃圾收集器定期重用。