在.net中爲什麼Garbage collector在超出範圍時不會銷燬對象?它爲什麼要等到下一個清理過程運行?爲什麼物體一旦超出範圍就不清洗?
回答
這是一個由Chris Sells和Chris Tavares於2003年秋季開展的項目,由微軟贊助。他們通過向每個對象添加引用計數字段並修改JIT編譯器,以便在引用超出範圍時自動減少計數,從而修改CLR(轉子版本)。當計數變爲零時自動運行終結器。
目標達到了,不再需要使用聲明。
手術成功,但病人死了。這些修改導致嚴重的性能下降。他們試圖診斷它,並在當時是領先的工具供應商的Compuware的幫助下呼籲。但不能釘住它。該博客文章發佈失敗is here,技術細節are here。
垃圾收集器在此之後得到了更多的尊重。自那時以來,我不知道進一步的嘗試。
我希望我能「收藏」答案... – Mehrdad 2012-01-14 02:50:06
該應用程序/系統可能正在忙於做其他事情。因此,立即進行GC運行可能會導致性能下降。系統會嘗試確定運行GC的最佳時間。
這將需要GC的引用計數形式。 .NET GC是mark-and-sweep類型。
對象不會超出範圍。對象的引用可以。編譯器可以很容易地跟蹤它,但是還有其他對同一個對象的引用嗎?這並不是微不足道的。
引用計數有2個主要問題:
- 編譯器生成額外的代碼每次引用傳遞,複製或刪除
- 當兩個物體互相引用您有內存泄漏的時間。
假設你聲明一個實例變量部門d1 = new department();現在,一旦d1超出範圍,哪個內存位置d1指向的內存不再可用。你可以給我一個情況,那是不正確的? – developer747 2012-01-01 16:52:02
假設構造函數'new Department()'將自己註冊到一個靜態列表中。 – 2012-01-01 16:59:32
@ user1110437「return d1;」怎麼樣? – Iridium 2012-01-01 16:59:42
那麼,不是過程,而是線程。
主要原因是性能:垃圾收集的過程很昂貴,因此「虛擬機」更喜歡留下一些「誤入歧途」的內存(好吧,不是真的:它仍然可以引用它)併爲新的內存分配內存需要時的對象。不過,它仍然會定期運行,因爲讓記憶迷失太久也無濟於事。
垃圾收集算法很多:請參閱here。垃圾收集算法的目的是儘可能少地從運行代碼吸血鬼。在物品超出範圍後立即收集垃圾並不適合該帳單...
因爲那麼每次對任何引用(對象成員,變量,集合項目等)進行分配/更改時都需要進行檢查。你需要跟蹤對象的所有引用,例如通過存儲計數並使其保持最新。這被稱爲引用計數,並且具有許多問題,從一般性能(每個引用分配需要比較和存儲器訪問)到存在併發時的同步開銷(如果兩個線程同時引用同一對象的引用會發生什麼?)以無法檢測週期(如果A指的是B和B指的是A,則兩個參考計數都不能降爲0,因此您泄漏內存或者仍然需要如下所述的「完整」GC)。
相反,大多數的垃圾收集器只是讓引用來來去去,如果他們需要收集,他們按照當前存在以確定哪些對象是使用(分別爲引用,可能被使用,因爲它們是可到達)並將其餘部分解除分配。顯然,這是很多工作,所以你只是偶爾做一次。還有一些更加精細的方法可以最大限度地減少平均收集的工作量,或者更傾向於收集更可能堆的區域。但一般問題仍然存在:一旦垃圾變成垃圾,你就找不到所有的垃圾,因爲這意味着每當參考變化時,就會遍歷整個垃圾堆。
- 1. 爲什麼超出範圍?
- 2. 爲什麼這不超出範圍
- 3. 爲什麼'this.data'超出範圍?
- 4. 爲什麼變量超出範圍?
- 5. 爲什麼VecMedian產生超出範圍?
- 6. 索引超出範圍,但爲什麼?
- 7. 爲什麼索引超出範圍? (Python)
- 8. 爲什麼指數超出範圍?
- 9. 參數超出範圍 - 卡洗牌
- 10. 爲什麼不打印出一個洗牌清單?
- 11. 「超出範圍」是什麼意思?
- 12. 超出範圍是什麼意思?
- 13. 爲什麼你必須處理()一個java.awt.Window超出範圍?
- 14. 爲什麼我得到一個List索引超出範圍?
- 15. 爲什麼我得到一個索引超出範圍例外?
- 16. 爲什麼我的變量不能超出範圍?
- 17. 不知道爲什麼數組超出範圍JAVA
- 18. Python的sys.argv超出範圍,不明白爲什麼
- 19. 爲什麼「超出範圍」不會引發'substring(startIndex,endIndex)'
- 20. 我不明白爲什麼我的變量超出範圍
- 21. 爲什麼Int 2^31不會超出GHCi的範圍?
- 22. 不明白爲什麼我收到'下標超出範圍'
- 23. 列表索引超出範圍,不知道爲什麼?
- 24. Python的指數超出範圍錯誤,不知道爲什麼
- 25. PreparedStatement拋出索引超出範圍時,它不超出範圍
- 26. 一旦指針超出範圍,內存是否會被釋放?
- 27. 要求一旦超出範圍內的功能
- 28. IndexError:字符串索引超出範圍,無法弄清楚爲什麼
- 29. 爲什麼java拋出參數索引超出範圍SQLerror
- 30. 它爲什麼會拋出索引超出範圍錯誤?
在這裏有一篇關於.Net垃圾回收器的好文章:http://www.simple-talk.com/dotnet/.net-framework/understanding-garbage-collection-in-.net/ – 2012-01-01 16:40:01