2014-10-01 83 views
0

我創建了一個包含堆對象的存儲器持有者類,並且我想 確定該對象的配置對於GC非常有用。是否可以確定在最後一個對象引用釋放之後正好放置的對象?

我想是這樣的:

myObj = null; //Immediately call to ~myObj() 
+0

終結器沒有確定性地調用。你可以用GC.Collect強制一個GC,但這會迫使GC運行 - 這是一個陡峭的懲罰 - 不這樣做(我把它提出來,因爲有人可能會推薦它)。它甚至不保證你已經設法刪除對象的所有強引用。你試圖做的是對付.NET Framework的一些設計哲學。我會試着找出一種遵循這些哲學的方法,而不是對付它們。 – vcsjones 2014-10-01 17:35:45

+0

我可以創建一個COM對象嗎?是否是IUnknown.Release在最後強調的參考去掉了? – 2014-10-01 17:37:32

+0

我知道,但我在一個小型庫中創建我的Memory類,供初學者使用,我希望他們對內存垃圾回收沒有任何幫助。 – 2014-10-01 17:38:43

回答

2

.NET框架和運行時爲使用非託管資源的應用程序提供了兩個功能。

  1. 確定性清理:該IDisposable接口允許代碼在特定的時間釋放資源,通過顯式或隱式地調用Dispose()方法。 (C#中的using聲明提供了這一呼籲隱性支持。)
  2. - 最終清理:在活動用戶無法通過調用Dispose()方法來釋放非託管資源,一個終結可以用來防止漏水長時間運行的應用程序隨着時間的推移,用戶代碼通常不應包含用戶定義的終結器;相反,創建(或使用現有的)類擴展了SafeHandle並實現了ReleaseHandle方法來定義發佈行爲。

注意IDisposable.Dispose()是確定性資源清理只有支持的機制。最終的清理是應該避免的非確定性回退。

2

不,你不能做到這一點。你應該簡單地使用IDisposable,因爲它意味着使用。

+0

好吧,我明白了! ,但我可以創建一個COM對象嗎? IUnknown.Release()在最後一次被強調的引用中被刪除了嗎? – 2014-10-01 17:42:38

+0

我對COM對象不太熟悉,但我認爲你可以在你的Dispose方法中調用'IUnknown.Release()'。使用'Dispose(bool)'方法注意http://msdn.microsoft.com/en-us/library/system.idisposable.aspx中託管資源和非託管資源的模式。 – 2014-10-01 17:48:21

0

COM對象希望在超出範圍時及時通知,但.NET不支持除Dispose之外的即時通知。您應該在處理方法中調用IUnknown.Release,但在調用IUnknown.Release之前必須確保任何人都不會再嘗試再次使用該COM對象。試圖使用Release之後的COM對象,或者僅僅試圖再次撥打Release,這是一種災難。

因此,我建議不要將COM對象本身的引用釋放給外部代碼。相反,讓持有對象的所有對象在鎖中向對象本身發送所有請求(以確保代碼不會嘗試同時訪問),並讓您的方法獲取鎖,請在對象上調用Release,然後使用使參考無效。任何未來試圖操作沒有被捕獲的對象都會導致NullReferenceException這不是很好,但仍然比在發佈後嘗試使用對象更好。