2012-04-05 93 views
2

当我声明int a = 0;,因为它是值类型它从堆栈获取内存,所以当这个变量超出范围垃圾回收器回收这个内存?垃圾回收器回收值类型的内存

+0

当然,它被标记为垃圾收集,但不一定实际上垃圾收集在那一点? – 2012-04-05 11:55:40

+13

您应该阅读Eric Lippert的[关于价值类型的真相](http://blogs.msdn.com/b/ericlippert/archive/2010/09/30/the-truth-about-value-types.aspx)。 – Oded 2012-04-05 11:56:36

+0

这里的第一个错误是你假设int a = 0;由CG收集 - 也许你的问题是任何数据转到CG ......或者在函数内部发生什么int值? – Aristos 2012-04-05 12:21:41

回答

16

当我声明int a = 0;因为它是值类型,它从栈中获取内存

这是正确的 - 假设局部变量是短暂的 - 但逻辑错误。当你声明任何短暂本地它从短期内存池获得它的内存,其中可能是是堆栈,或者它可能是一个寄存器。无论它是值类型还是对引用类型的引用,它都从短期池中获取内存。无论哪种方式,如果变量是短暂的,则内存将分配到短期池中。

也就是说,当你有一个短暂的局部

object x = null; 

的为对象参考是在短期内池分配存储。引用对象的存储(如果存在的话)将分配给长期池,即堆。在这种情况下,参考为空。

当这个变量超出范围时垃圾回收器是否回收这个内存?

号的垃圾收集只收集了长远池,也被称为堆分配的内存。

垃圾收集器当然必须知道短期池;如果在短期池中存在参考文献,那么这些参考可能是存在的事情。但垃圾收集器可以安全地忽略所有值类型,这些值不包含在短期池中的引用

你为什么问这个问题?我怀疑这里隐藏着更深的问题。

+0

埃里克,我正在寻找的东西,仍然 - (相关),阅读你的文章,你说 - 看着堆栈,将指针移动一步 - 非常简单便宜 - 因此我们使用它 - 。但是** DO **对于长寿命对象的参考价值类型呢?这不会影响_weep_部分的性能吗?我的意思是,如果'pop()'不能'pop()',那么它是如何完成的 - 因为它引用了堆中一个很长的活物体... – 2014-02-16 14:31:28

+0

@RoyiNamir:你已经知道了它。你说你不能弹出堆栈,因为堆栈指的是活着的东西,但事实恰恰相反。这个东西是活着的*,因为它被堆栈引用*。当堆栈弹出时,必须有*别的东西*保持被引用对象的存在;如果没有,那么它已经死了。 – 2014-02-18 01:47:42