是指针的堆栈内存,对象的堆内存

本文关键字:内存 对象 堆栈 指针 | 更新日期: 2023-09-27 18:06:18

首先,我目前在c#中工作,我一直在阅读内存管理。到目前为止,我已经阅读了一些关于堆栈溢出的好答案,解释了堆栈内存和托管堆内存之间的区别。大多数答案通过声明:
int x = 5,您在堆栈内存中为x类型分配了足够的内存。

我理解这是如何工作的,以及它的范围,但是当我阅读堆内存的解释时,它让我感到困惑。

如果你说int x = 5,因为intSystem.Int32的别名,x在技术上不是指向System.Int32结构体的新实例的指针吗?如果是这样,难道它不会被存储在堆内存中吗?因为堆内存是用于实例对象的。

在本教程中,它表示(对于class1 cls1 = new class1()行):

…在堆栈上创建一个指针,而实际对象存储在另一种称为"堆"的内存位置中。

根据这个逻辑,不是所有的东西都存储在堆上,只有指针存储在堆栈上吗?示例为System.String, System.Int64, System.Boolean, System.Decimal等的新实例

我以为我理解它,但显然我没有,所以我很感激有人解释堆栈是否只用于指针或哪一部分我误解了。

是指针的堆栈内存,对象的堆内存

您可以使用以下规则:如果它是一个结构体(包括基本类型),则在声明它的地方分配,否则在堆中分配指向对象的指针。

可能的位置有:

  1. 对于局部变量,它是一个堆栈。请注意,物理值可以存储在CPU寄存器中,而不是堆栈中。
  2. 对于类字段,它位于为类的实例在堆中分配的连续内存块内。
  3. 对于静态字段,它在加载器堆中分配为类型元数据的一部分(如果我错了请纠正我)。

警告:这只是一个基本的,不全面的解释,对正在发生的事情有一个基本的了解。现实情况要复杂得多。局部变量可以提升并移动到堆中,优化器可以完全消除它们,等等…

您可能需要检查类和结构(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)。