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

时间:2011-09-08 05:39:05

标签: c# memory-management

As Value类型变量在Stack中分配内存,其中Reference Type在Heap中分配它。

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

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

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

由于

4 个答案:

答案 0 :(得分:18)

  

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

不,那句话是完全错误的。很多人都相信,但是你发现它显然是假的。

  

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

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

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

  • 值类型
  • 引用
  • 参考类型的实例

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

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

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

变量是一个存储位置,存储值类型引用

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

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

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

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

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

答案 1 :(得分:6)

这就是Eric Lippert提醒我们the stack is an implementation detail.

的原因

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

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

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

答案 2 :(得分:2)

  

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

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

答案 3 :(得分:1)

这是一个很好的article

顺便说一句:并不总是在堆栈上找到一个值 - 它可能以堆形式结束。