2009-11-08 77 views
3

我對.net比較陌生。正如我試圖掌握垃圾收集的概念(從「通過C#的CLR」),我開始瞭解垃圾收集方法的強大程度。但是,當我閱讀時,我明白應該釋放分配的本地資源。其方法爲:
我)讓我們的類型從CriticalFinalizerObject
ii)使用處置利用格局使用語句在我的腦海C# - 發佈本地資源

問題得出:
1)我有點困惑時使用什麼?
2)對於CLR來說,將非垃圾對象向下移動來壓縮堆也不是更重要嗎?
3)任何其他文章建議閱讀和理解更徹底的概念。

請糾正我,如果我在我的任何上述聲明
問候,
賈斯汀·塞繆爾的錯。

+0

感謝所有的意見。傾聽來自你們的想法,幫助很多!謝謝!! :) – 2009-11-09 05:26:26

回答

4
  1. 要從CriticalFinalizerObject在你的類型的使用應被視爲一個constrained execution region或CER短的情況下獲得。 CER是一個必須完成的代碼領域,根據我的經驗,這些代碼通常不會被使用(但這並不意味着它們沒有用處)。

    執行IDisposable接口有點不同 - 這種接口提供了一種確定性的清理方式,一旦消費者不再需要,就可以在你的類型後進行清理。這通常用於清理非託管資源(如數據庫連接和文件句柄)。

  2. 是的,垃圾收集器必須在其緊湊階段將許多對象移動到內存中,但這並不是真的可以提供幫助。當虛擬內存變得碎片化時,對象將被移動,這是不受控制的,因爲垃圾收集器完全負責託管堆。在這種情況下,最好的做法是讓您的類型儘可能最好地工作,並且只有在儀器證明它​​已成爲問題時才擔心垃圾收集器。

  3. 我會看看我是否可以找到一些更有用的文章,但CLR通過C#幾乎是最好的信息,你將能夠找到關於這個主題。

+0

是的安德魯,你是對的。 「通過C#CLR」是從概念上學習.net的絕佳資源。你能建議我學習c#概念的好鏈接嗎? – 2009-11-09 05:28:01

2

儘可能使用Dispose模式和using。只有在無法確定性地知道何時可以釋放特殊資源時才使用終結器。如果你發現這種情況經常發生,你可能做錯了什麼。

垃圾收集是一個很深的話題。有關垃圾收集的總體概述及其在CLR中的實現,特別是this article似乎很穩固。這是從十年前開始的,但好的CS就像是好的數學:它的年齡很好。

3

我推薦這篇文章在Dispose, Finalization, and Resource Management

你使用什麼取決於你做什麼類型的編程。根據個人經驗,我發現:

  • 大多數情況下,我唯一需要做的資源管理是將任何實現IDisposable的對象封裝在使用塊中。
  • 當我的類擁有一個實現IDisposable的對象時,有時我必須實現Basic Dispose Pattern(無終結器)。
  • 我從來沒有必須從CriticalFinalizerObject派生。

您的里程可能會有所不同。

0

安全與非託管手柄

工作可靠釋放非託管手柄而不約束的執行區域(的CER)是不可能的。由於ThreadAbortOutOfMemory例外可能會出現在您的終結器中,您總是會遇到競爭狀況。所以你需要使用CERs。

CriticalFinalizerObject在內部使用約束執行區域,在最終化過程中優先化,還有一些其他功能使得它「相對容易」相對容易,並且在需要時總是釋放非託管資源。一般情況下,你應該從SafeHandleCriticalFinalizerObject派生手柄握住非託管對象。這樣你就知道當物體被垃圾收集時它們會被清理乾淨,即使它是一種不尋常的關機情況,如ThreadAbortException

使用什麼()和IDisposable的增加

using()和IDisposable模式讓你急切地釋放非託管資源 - 如您使用的是他們做盡快。如果你不用using()來處理你的對象,他們會堅持到下一次垃圾收集。這是低效率的。

所以CriticalFinalizerObject是關於如何確保非託管資源最終釋放而using()是關於如何確保非託管資源被迅速釋放。兩者應該一起使用。

另外using()適用於純粹的託管代碼,例如,如果您正在緩存一個對象池,則Dispose()可以將對象返回到池中。

GC

壓實堆可以更有效,因爲持續時間長的對象最終都擠在一起時壓實堆。在.NET Framework中,只有最低的一代(最近創建的對象)被嚴格壓縮。 Theres在引擎蓋下進行了很多優化。閱讀起來很有趣,但對於完成工作並不重要。如果您想了解更多信息,請搜索關於「世代垃圾收集」的文章。