我對C#中只有引用類型被垃圾收集的事實感到有點困惑。 這意味着GC僅挑選存儲器取消分配的參考類型。 那麼值類型會發生什麼,因爲它們也會佔用堆棧中的內存?在C#中銷燬結構對象?
回答
一開始,無論他們是堆的堆或部分依賴於什麼情況下他們的一部分 - 如果他們是引用類型之內,他們將在堆上反正。 (你應該考慮多少你真的關心棧/堆鴻溝無論如何 - 作爲埃裏克利珀寫,這是largely an implementation detail)
然而,當上下文被收回基本值類型的內存被回收 - 所以即使堆棧你從方法返回時彈出,「回收」整個堆棧幀。同樣,如果值類型值實際上是對象的一部分,那麼當對象被垃圾收集時,內存將被回收。
簡短的回答是,你不必擔心它:)(這裏假設你沒有任何東西其他比內存擔心,當然 - 如果你已經有了引用的結構對需要釋放原生手柄,這是一個有些不同的情景。)當堆棧幀被刪除,已執行後,我會承擔
堆棧中的值類型超出範圍時將從堆棧中刪除。
值類型一旦超出範圍就會被銷燬。
值類型將得到釋放
還要補充一點,堆在一個線程級別,並且堆在應用程序域級別。
所以,當一個線程結束,將通過RECLAM特定線程使用的堆棧存儲器。
有在這個問題上使用,比如破碎,回收,重新分配,除去過多的動詞。這與實際發生的情況並不相符。局部變量根本不復存在,Norwegian parrot style。
的方法,具有一個入口點,即首先發生的事情是,CPU堆棧指針調整。創建一個「堆棧框架」,即本地變量的存儲空間。 CLR保證這個空間被初始化爲0,而不是因爲明確的分配規則而在C#中強烈使用的功能。
的方法有出口的一個點,即使你方法的代碼穿插着多個return
語句。此時,堆棧指針會簡單地恢復到其原始值。實際上,它「忘記」那裏的局部變量。它們的值不以任何方式「擦除」,字節仍然存在。但是它們不會持續很長時間,您的程序中的下一次呼叫將會再次覆蓋它們。 CLR零初始化規則確保您永遠不會觀察那些不安全的舊值。
非常非常快,只需要一個處理器週期。這種行爲在C#語言中的可見副作用是值類型不能有終結器。確保不需要做額外的工作。
這個局部變量已經不存在了!它已不復存在!這是一個前變量。 :) – 2015-12-05 08:03:08
我對C#中只有引用類型被垃圾收集的事實感到困惑。
這不是事實。或者說,這個陳述的真實性或虛假性取決於你的意思是「收集垃圾」。垃圾收集器在收集時肯定會查看值類型;這些值類型可能還活着,並持有到引用類型:
struct S { public string str; }
...
S s = default(S); // local variable of value type
s.str = M();
在垃圾收集器運行時,它看起來確實在s,因爲它需要確定s.str還活着。
我的建議:澄清精確地您的動詞「獲取垃圾收集」意味着什麼。
GC僅挑選存儲器取消分配的參考類型。
同樣,這不是事實。假設有的
class C { int x; }
爲整數存儲器中的實例將是對垃圾收集堆,並且因此被垃圾收集器回收時C的實例變爲無根。
爲什麼你認爲只有引用類型的內存被垃圾收集器釋放的假?正確的說法是被垃圾回收器分配爲的內存是,垃圾回收器取消分配了,我認爲這很有道理。 GC分配它,所以它負責清理它。
那麼值類型會發生什麼,因爲它們也會佔用堆棧中的內存?
沒有什麼事情發生在他們身上。沒有什麼需要發生在他們身上。該堆棧是一百萬字節。線程啓動時確定棧的大小;它始於一百萬字節,並且在整個線程執行期間它保持一百萬字節。堆棧中的內存既不被創建也不被破壞;只有其內容被改變。
「堆棧中的內存既不被創建也不被破壞」 - 我建議我們稱之爲** Lippert內存保存法則**。 :) – 2010-01-27 19:11:26
.NET中的每個值類型實例都是其他內容的一部分,可能是更大的封閉值類型實例,堆對象或堆棧幀。每當這些事情產生時,其中的任何結構也會產生;那麼只要包含它們的東西確實存在,那些結構就會繼續存在。當包含結構的東西不復存在時,結構也會如此。在沒有破壞容器的情況下,沒有辦法摧毀一個結構,並且無法銷燬包含一個或多個結構的東西而不破壞其中包含的結構。
- 1. C++銷燬對象
- 2. 在X ++中銷燬對象
- 3. 銷燬對象
- 4. 對象銷燬
- 5. 銷燬C中的非託管對象#
- 6. 如何銷燬C#中的COM對象?
- 7. 銷燬Ember.js中的對象
- 8. C++ - 對象在析構函數執行前被銷燬
- 9. 一次銷燬對象的整個層次結構
- 10. 如何在JavaScript中銷燬對象?
- 11. 無法在Rails中銷燬對象
- 12. 部分構建和銷燬層次結構中的兒童課程對象
- 13. 如何銷燬PDFJS對象?
- 14. 如何銷燬java對象?
- 15. RSpec與Factory_girl - 銷燬對象
- 16. Python:全局對象銷燬
- 17. 銷燬Oracle PLSQL對象
- 18. 何時銷燬對象?
- 19. 銷燬對象的::地圖
- 20. 銷燬對象的錯誤
- 21. 銷燬主類對象
- 22. 銷燬停用對象
- 23. 銷燬成員對象
- 24. 如何在C中銷燬一個對象#
- 25. Unity2d - 銷燬對象使用銷燬(gameObject)//它會銷燬與腳本連接的對象
- 26. C#通過Excel過程銷燬多個Excel對象的正確方法銷燬
- 27. 摧毀主要對象時銷燬嵌入對象
- 28. Ruby中對象銷燬的通知
- 29. 對象在返回之前被銷燬
- 30. 書寫方法銷燬並創建鏈接銷燬對象
感謝您參考此綜合性文章。我發現Eric Lippert的全局指令與整個c#哲學非常一致:「只關注語義,我們會爲你處理其餘的問題」 – 2013-12-10 15:32:34