类中声明的变量的内存分配

由于Value类型变量在Stack中分配内存,因为Reference Type在Heap中分配它。

那么在引用类型(例如,在类中)声明值类型变量(例如int i = 4;)时分配的内存如何。

整个内存分配如何在.net中用于值类型和引用类型,以及在refence类型范围内的值类型。

请解释或提供有关的任何链接。

谢谢

那么在引用类型(例如,在类中)声明值类型变量(例如int i = 4;)时分配的内存如何。

如果对象位于堆上,则意味着它所有的成员变量就在那里。

值类型变量在堆栈上分配内存,而引用类型在堆中分配它。

不,这种说法是完全错误的。 很多人都相信,但你发现它显然是假的。

当值类型变量int i = 4;时,如何分配内存int i = 4; 被声明为引用类型的字段?

显然你知道为什么你的第一个陈述是完全错误的。 无法在堆栈上分配类的整数字段,因为该对象可能比堆栈帧寿命更长。

要了解实际情况,首先要了解有三种情况:

  • 价值类型
  • 引用
  • 引用类型的实例

参考 类型参考类型的实例完全不同,就像一张包含我的地址和我的实际房屋的纸张完全不同。

接下来要了解的是存储有两种存储方式:长期存储和临时存储。 长期存储通常被称为“堆”,但我更愿意将其视为长期存储。 临时存储通常被称为“堆栈”,但这也具有误导性,因为当然可能存在多个堆栈,可能存在寄存器中的临时存储,等等。

引用类型实例占用长期存储中的内存。 (有时可以确定引用类型的实例是短暂的,并将其放在临时存储中,但我们在实践中不进行此优化。)

变量是存储值的类型引用的存储位置。

分配变量的存储位置取决于变量的生命周期 。 如果变量是已知寿命较短的局部变量,则从临时存储池中分配该变量。 如果已知变量具有较长的生命周期(因为,例如,它是闭包的外部变量),那么它将从长期存储池中分配出来。

如果变量是类的字段,我们已经知道它的存储来自长期池。 如果变量是值类型的字段,则该值类型驻留在某处的存储中; 这个领域居住在同一个仓库里。

如果变量是数组元素,则从长期存储池中分配; 数组是引用类型的实例。

让您理解正确的关键是简单地停止相信变量是参考变量还是值类型影响存储分配位置的神话。 这不是真的,从来都不是真的,甚至没有任何意义。

影响变量存储位置的唯一因素是变量存活多长时间 。 从临时池(堆栈或寄存器)分配短期变量,并在长期存储池(堆)之外分配长期变量。

这就是为什么Eric Lippert提醒我们堆栈是一个实现细节。

当值类型的实例是引用类型yes的成员时,它将与父对象一起存储在托管堆上。 这是一个很好的问题和你应该理解的东西,而不是在大多数情况下应该驱动你的设计的东西。

structs应该是小的,简单的数据类型,创建和传递相对便宜。 引用类型是您的复杂类型,只需要传递给方法的引用副本,但当然由于在堆上分配而带来一些包袱。 关于堆栈与堆分配的含义,这是一篇很好的后续post 。

有很多参考资料可以解释价值类型与参考类型的性能影响。 您应该了解所有相关内容,并了解大多数情况下,这是一个语义决策,而不是一个绩效决策。

这是一篇很好的文章 。

顺便说一句:并非总是在堆栈上成为一个价值 – 它可能以堆结束。