2010-02-26 118 views
17

我知道參考類型將被垃圾收集。我想知道價值類型是否也會從堆棧中收集垃圾?值類型是否收集垃圾收集?

+0

你能仔細地定義什麼是「垃圾回收」對你意味着什麼? – 2010-02-26 15:47:07

+0

我的意思是「垃圾收集」,如果發現值類型變量不被應用程序使用,那麼它將從堆棧中移除。 – csharpbaby 2010-02-26 15:59:09

+0

我想Eric很清楚地解釋了這一點,但讓我直接回答一下,只是爲了確保:只要在範圍內,局部變量將保持分配狀態,而不管是否有其他引用。它不受收集,只是範圍。 – 2010-02-26 16:04:44

回答

31

你的問題意味着什麼非常不清楚。你能否仔細確定「垃圾收集」的含義?它是指「是GC算法的輸入」,還是「通過壓縮GC堆釋放」,或者是什麼?

存儲在堆棧上的值 - 值類型或引用類型的值是集合算法的。他們是沒有收集因爲他們是活着的東西,讓幾乎所有的東西都活着。

很明顯,他們沒有通過壓縮GC堆來釋放;他們通過彈出堆棧來釋放。

這是否回答你的問題?

UPDATE:

我的意思的「垃圾收集」是 ,如果一個值類型變量是 發現不是由 應用則它將從堆棧

去除 可以使用

好的,我們在這裏越來越接近可回答的問題。現在我們需要通過「從堆棧中移除」來理解你的意思。

該堆棧是大小爲的預分配內存百萬字節塊。有時我們使用該塊內存的一部分來存儲值類型的局部變量。 「從堆疊中取出」是什麼意思?堆棧的大小不會改變;它是一個100萬字節的預分配內存塊。

堆棧被分成兩個連續的區域,我們稱之爲堆棧的「有效」和「無效」部分。在x86架構上,ESP寄存器指向這些區域之間的邊界。你在問:「在什麼情況下,基於x86體系結構上ESP寄存器值的變化,堆棧中與某個特定類型的局部變量相關的內存是否成爲無效部分的一部分?」

這可能看起來像是一個非常非常「實施細節」的問題。 堆棧是運行時特定版本的實現細節,因此如果您要提出關於它的問題,您將不得不接受一個事實,即您正在詢問特定的特定值在特定的芯片架構上註冊。

延伸閱讀:

http://blogs.msdn.com/ericlippert/archive/2009/02/17/references-are-not-addresses.aspx

http://blogs.msdn.com/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx

http://blogs.msdn.com/ericlippert/archive/2009/05/04/the-stack-is-an-implementation-detail-part-two.aspx

http://blogs.msdn.com/ericlippert/archive/2009/06/08/out-of-memory-does-not-refer-to-physical-memory.aspx

我現在有點糊塗讀你所提到的 「價值觀」,什麼「v類型「。我發現很難理解這種差異。

這很棘手!我們用「價值」和「參考」來表示太多的東西。讓我總結一下。

變量是存儲位置

每個變量都有一個類型。一種類型可以是值類型參考類型

存儲位置包含

值類型變量的值是值類型的值。例如,int是一個值類型。 int類型變量的值是一個整數,例如12。

引用類型變量的值是對該類型對象的引用,或爲null。例如,字符串是一個引用類型。字符串類型的變量的值是對字符串的引用,或者是null。

這就是爲什麼他們被稱爲「價值類型」和「參考類型」。值類型的值是該類型的一個實例。引用類型的值是對類型實例的引用。

現在有道理嗎?

+0

謝謝。這清除了我所有的疑惑:-)。感謝這個優秀的解釋。 (PS:我是你的粉絲,我通過分享你博客的知識給我的朋友留下了深刻印象!) – csharpbaby 2010-02-26 16:30:01

+0

@csharpbaby:不客氣。我已經在上面的文章中提供了一些您可能會感興趣的博客文章的鏈接。 – 2010-02-26 16:33:22

7

公共語言運行庫(CLR)爲兩個地方的對象分配內存:堆棧和堆。

值類型與對存儲在堆中的引用類型內容的引用一起存儲在堆棧上。垃圾收集器的要點是當從堆棧中彈出引用時,釋放分配給堆上引用類型內容的內存。

不是引用類型內容的值類型不存儲在堆中,因此它不會被垃圾回收器清理。

See here for a slightly more in depth description of value vs reference types

See here for a lot more in depth description

+4

值類型不一定存儲在堆棧上。正確的說法是:「值類型的值是臨時存儲或本地變量,它們不是封閉式的,而是不在迭代器塊中的匿名方法或lambda表達式的局部變量,它們存儲在CLI的Microsoft實現的堆棧中。 「不在GC堆上的值類型不會被垃圾收集器清理。垃圾收集器清理GC堆上的*爲*的值類型。 – 2010-02-26 16:02:17

+1

+1同意,但試圖將其轉換爲簡單易懂的清晰簡明答案是一項挑戰;-) – 2010-02-26 16:10:09

+0

您是對的。在Eric寫下「價值型的價值觀」後,我想我現在非常努力地思考。 :) – csharpbaby 2010-02-26 16:16:00

1

假設你的意思是「垃圾收集」中,如果他們還活着的垃圾收集器檢查,然後回收內​​存的意義,那麼答案是不,他們不是「垃圾收集」 。

原因是當堆棧幀被移除時,堆棧上的內存自動回收。

對這篇文章的讀:http://en.wikipedia.org/wiki/Stack_%28data_structure%29#Hardware_stacks

+0

謝謝保羅。我會閱讀這篇文章:) – csharpbaby 2010-02-26 16:10:07