繁体   English   中英

类中声明变量的内存分配

[英]Memory Allocation for Variable Declared in Class

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

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

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

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

谢谢

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

不,这种说法是完全错误的。 很多人相信这一点,但正如您所发现的,这显然是错误的。

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

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

要了解真正发生的事情,首先您必须意识到存在三种情况:

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

引用引用类型的实例是完全不同的,就像一张纸上写着我的地址和我的实际房子是完全不同的。

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

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

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

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

如果变量是一个类的字段,我们已经知道它的存储来自长期池。 如果变量是值类型的字段,则该值类型驻留在某处的存储中; 该字段位于相同的存储中。

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

正确理解的关键是不要再相信变量是引用类型还是值类型会影响存储分配位置的神话。 那不是真的,从来都不是真的,甚至没有任何意义。

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

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

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

structs应该是小而简单的数据类型,创建和传递的成本相对较低。 引用类型是您的复杂类型,只需要将引用的副本传递给方法,但由于在堆上分配,当然会带来一些负担。 这是关于堆栈与堆分配的影响的很好的后续帖子

有很多参考资料解释了值类型与引用类型的性能影响。 您应该了解所有相关信息,并了解大多数情况下,这是一个语义决策,而不是性能决策。

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

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

这是一篇不错的文章

顺便说一句:并非总是在堆栈上有一个值 - 它可能在堆中结束。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM