2015-04-06 60 views
1

我聽說垃圾收集會導致不良的軟件設計。真的嗎?確實,我們不關心垃圾收集語言中對象的生命週期,但是這對程序設計有什麼影響?垃圾收集是否會導致軟件設計不良?

+0

我從來沒有聽說過。我經歷過GC導致更好的軟件設計。 – 2015-04-08 10:29:18

回答

2

如果一個對象要求其他對象代表它做某件事,直到另行通知,對象的所有者應該在不需要它的服務時通知它。讓代碼放棄這些對象而不通知他們不再需要他們的服務將是不好的設計,但這在垃圾收集框架中與在非GC框架中一樣正確。

垃圾收集框架,適當地使用,提供了兩個優點:

  1. 在許多情況下,對象被用於在其中包封值的目的而創建,向對象的引用被作爲代理爲圍繞通過數據。接收這種引用的代碼不應該關心其他引用是否存在於這些相同的對象,或者它是否包含最後存活的引用。只要有人持有對象的引用,就應該保留這些數據。一旦沒有人需要這些數據,它就不應該存在,但沒有人應該特別注意。

  2. 在非GC框架中,嘗試使用處置對象通常會生成無法可靠捕獲(並可能允許代碼違反安全策略)的未定義行爲。在許多GC框架中,可以確保使用處置資源的嘗試將被確定性地困住,並且不會破壞安全性。

在某些情況下,垃圾收集將允許程序員是更模糊比將在非GC系統是可以容忍的設計「以矇混過關」。然而,基於GC的框架也允許使用很多好的編程模式,這些編程模式在非GC系統中無法高效地實現。例如,如果一個程序使用多個工作線程爲問題尋找最佳解決方案,並且有一個UI線程週期性地想要顯示迄今爲止找到的最佳解決方案,那麼UI線程會想知道當它詢問一個狀態更新它會得到一個解決方案已被發現,但不希望負擔工作線程的必要同步,以確保它有絕對最新的解決方案。

在非GC系統中,線程同步將是不可避免的,因爲UI線程和工作線程必須協調誰將刪除狀態對象,該狀態對象在顯示時會變得過時。然而,在一個基於GC的系統中,GC將能夠判斷一個UI線程是否能夠在狀態對象被替換之前獲取一個對狀態對象的引用,從而解決該對象是否需要保持足夠長的時間UI線程來顯示它。 GC有時必須強制線程同步才能找到所有可到達的引用,但偶爾爲GC進行同步的性能消耗可能會低於非GC系統中所需的頻繁線程同步。

+0

非GC語言可以很容易地捕獲Use-After-Dispose。但他們通常不會處理東西,而是刪除它們。 – 2015-04-08 10:28:14

+0

@HenkHolterman:跟蹤GC語言可以保持一個絕對不變量,只要有任何可以想象的代碼路徑可以通過它來訪問一個對象的引用,引用永遠不會被解釋爲識別其他任何東西。我能想到的提供這種保證而沒有追蹤GC的最實際的方法是引用包含句柄而不是直接指針,並且每個引用都包含一個序列號,這樣即使句柄被回收了,序列號也不會與任何現有的引用相匹配。我想不出任何... – supercat 2015-04-08 15:05:36

+0

...替代方法的開銷較小,但必須保持每個參考序列號的同時檢查每次訪問似乎相當昂貴,而使用跟蹤GC。 – supercat 2015-04-08 15:06:07