C# 堆栈内存是否仅用于指针和堆对象?
首先,我目前在C#工作,我一直在阅读有关内存管理的书籍。到目前为止,我已经阅读了有关堆栈溢出的一些很好的答案,解释了堆栈内存和托管堆内存之间的区别。大多数答案都声明:C# 堆栈内存是否仅用于指针和堆对象?,c#,pointers,memory,heap-memory,stack-memory,C#,Pointers,Memory,Heap Memory,Stack Memory,首先,我目前在C#工作,我一直在阅读有关内存管理的书籍。到目前为止,我已经阅读了有关堆栈溢出的一些很好的答案,解释了堆栈内存和托管堆内存之间的区别。大多数答案都声明: int x=5,您正在堆栈内存中为x类型分配足够的内存。 我了解它的工作原理和范围,但是当我阅读堆内存的解释时,我感到困惑。 如果你说的是int x=5,因为int是System.Int32的别名,那么x从技术上讲不是指向System.Int32结构的新实例的指针吗?如果是这样的话,它会不会存储在堆内存中,因为堆内存用于实例对象。
int x=5
,您正在堆栈内存中为x
类型分配足够的内存。我了解它的工作原理和范围,但是当我阅读堆内存的解释时,我感到困惑。
如果你说的是
int x=5
,因为int
是System.Int32
的别名,那么x
从技术上讲不是指向System.Int32
结构的新实例的指针吗?如果是这样的话,它会不会存储在堆内存中,因为堆内存用于实例对象。在教程中,它声明(对于行
class1 cls1=new class1()
):
... 在堆栈上创建一个指针,而实际对象存储在另一种称为“Heap”的内存位置。按照这种逻辑,不是所有的东西都存储在堆上,只有指针存储在堆栈上吗?示例为
System.String
,System.Int64
,System.Boolean
,System.Decimal
等的新实例。我想我理解它,但我不清楚,所以我希望有人能解释一下堆栈是否只用于指针,或者我误解了哪个部分。提前感谢。您可能需要检查以了解什么存储在何处以及如何存储:
int x = 1; // 32 bits holding an integer in the stack
System.Object bo = x; // 32+some more bits are on the heap to hold the "boxed" (wrapped to be kept on the heap) integer value
System.Object ho = new Object(); // some bits are created on the heap right from the start
简单地说,有两种类型的对象:类和结构。类(引用类型)将存储在堆上,并有一个指向它们的指针,而结构将存储在堆栈中(结构可以重新定位到堆上,但包装(“装箱”)它们的开销很小)
如果您真的需要/想要理解CLR一般是如何工作的,请考虑阅读“CR通过C.*”(李希特)。
您可以使用以下规则:如果它是一个结构(包括基元类型),那么它就被分配到声明的地方,否则就分配给堆中对象的指针。 可能的地点包括:
警告:这只是一个基本的、不全面的解释,对发生的事情有一个基本的了解。现实更为复杂。局部变量可以被提升并移动到堆中,优化器可以完全消除它们,等等。
系统。Int32
是一个结构,而不是一个类。因此,作为本地,它可能会在堆栈上分配。请记住,.NET CLR正在更改,“已分配的堆”和“已分配的堆栈”之间的行将继续变得更模糊。教程是错误和不完整的。@Nathangrad结构在C#中不能为null。结构是值类型。没有要为null的引用。C#编译器可能会在“使用未初始化变量”时出错,但这只是编译器试图提供帮助的地方。然后,如果您有很多空闲时间,您可以阅读ECMA规范。如果您想添加更多,您应该编辑您的答案。不需要自己直接评论(问题/答案),这比“值类型存储在堆栈上,引用类型存储在堆上”更复杂。类[…]在堆栈中有指向它们的指针
指针不一定在堆栈上。它可能在堆栈上,适用于任何值,正如Joshua所指出的,这也会使同一句话的后半部分出错。正如我(和Joshua)之前所说,句子的其余部分仍然是错误的。对于未加权的局部变量,它可能是堆栈。如果您想更精确,请参阅注释中链接到的Eric Lippert帖子。是的,已提升的变量成为显示(闭包)类的字段,即使未提升该变量,也可能无法使用堆栈。它可能严格使用注册,也可能被完全优化。我刚刚用谷歌搜索了你在答案中使用的80%的技术术语,但我想我理解。谢谢