是指针的堆栈内存,对象的堆内存
本文关键字:内存 对象 堆栈 指针 | 更新日期: 2023-09-27 18:06:18
首先,我目前在c#中工作,我一直在阅读内存管理。到目前为止,我已经阅读了一些关于堆栈溢出的好答案,解释了堆栈内存和托管堆内存之间的区别。大多数答案通过声明:int x = 5
,您在堆栈内存中为x
类型分配了足够的内存。
我理解这是如何工作的,以及它的范围,但是当我阅读堆内存的解释时,它让我感到困惑。
如果你说int x = 5
,因为int
是System.Int32
的别名,x
在技术上不是指向System.Int32
结构体的新实例的指针吗?如果是这样,难道它不会被存储在堆内存中吗?因为堆内存是用于实例对象的。
在本教程中,它表示(对于class1 cls1 = new class1()
行):
…在堆栈上创建一个指针,而实际对象存储在另一种称为"堆"的内存位置中。
根据这个逻辑,不是所有的东西都存储在堆上,只有指针存储在堆栈上吗?示例为
System.String
, System.Int64
, System.Boolean
, System.Decimal
等的新实例我以为我理解它,但显然我没有,所以我很感激有人解释堆栈是否只用于指针或哪一部分我误解了。
您可以使用以下规则:如果它是一个结构体(包括基本类型),则在声明它的地方分配,否则在堆中分配指向对象的指针。
可能的位置有:
- 对于局部变量,它是一个堆栈。请注意,物理值可以存储在CPU寄存器中,而不是堆栈中。
- 对于类字段,它位于为类的实例在堆中分配的连续内存块内。
- 对于静态字段,它在加载器堆中分配为类型元数据的一部分(如果我错了请纠正我)。
警告:这只是一个基本的,不全面的解释,对正在发生的事情有一个基本的了解。现实情况要复杂得多。局部变量可以提升并移动到堆中,优化器可以完全消除它们,等等…
您可能需要检查类和结构(MSDN),以了解哪些内容存储在何处以及如何存储:
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是如何工作的,可以考虑阅读"CLR via c# " (Richter)。