2012-04-05 96 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