簡體   English   中英

GC、Finalize() 和 Dispose 之間的關系是什么?

[英]what is relation between GC, Finalize() and Dispose?

GC 用於托管對象,Finalize 用於非托管對象,這就是我一直在閱讀的內容。 Dispose 是隱式的,Finalize 是 Explicit 是我一直在閱讀的內容。 有人可以給我一個模塊的示例,其中出於不同原因使用了所有三樣東西嗎?

GC 是垃圾收集。 它是自動內存管理,處理在托管堆上分配的對象的清理。 .NET GC 使用標記和清除算法。 當垃圾收集發生時,它基本上認為要清理的堆部分中的所有對象都是可恢復的。 然后它會通過一個標記過程來掃描根。 即它標識應用程序仍在使用的對象。 完成后,剩余的對象有資格進行清理。 作為清理的一部分,堆可能會被壓縮。

Dispose 和 finalizer 方法都提供了清理資源的選項,這些資源不由GC 處理。 例如,這可以是本機句柄等。 它們與回收托管堆上的內存無關。

Dispose 必須在實現IDisposable的類型上顯式調用。 它可以通過Dispose()方法本身或通過using構造調用。 GC 不會自動調用 Dispose。

另一方面,終結器或析構器(如語言規范所稱)將在對象符合清理條件后的某個時間自動調用。 Finalize 方法在專用線程上按順序執行。

Dispose()允許確定性地清理資源,而終結器可以充當安全網,以防用戶不調用Dispose()

如果類型實現了終結器,則實例的清理會延遲,因為必須在清理之前調用終結器。 即它需要一個額外的收集來回收該類型實例的內存。 如果該類型也實現了 IDisposable,則可以調用 Dispose 方法,然后該實例可以將自身從終結中移除。 這將允許對象被清理,就好像它沒有終結器一樣。

如果您想深入研究這一點,我建議您通過 Jeffrey Richter 的 C#使用CLR 這是一本很棒的書,它涵蓋了這方面的所有血腥細節(我遺漏了一些細節)。 新的第三版剛剛發布。

.NET 的優點之一是垃圾收集器。 在許多語言中,每一塊內存都必須由開發人員管理——任何分配的內存最終都應該被釋放。 在 .NET (C#) 中,垃圾收集器 (GC) 將負責為您釋放內存的過程。 它跟蹤您的對象的使用情況,並且在它們成為“無根”之后(即:您的應用程序中沒有對該對象的直接或間接引用),該對象的內存將被自動清理。

Dispose,或者更具體地說, IDisposable和 Dispose 模式用於與 GC 分開處理資源。 由於各種原因,某些資源需要明確清理 這包括使用“本機”API(其中 .NET 不知道分配的內存)、使用包裝本機句柄的資源等。為了干凈利落地處理這個,您實現了IDisposable和 Dispose 模式。

當對象即將被垃圾收集器收集時,會在對象上進行終結。 這提供了一個“安全網”,如果比理想情況晚一點,本應該被處理的對象仍然可以被清理。 通過實現終結器,您可以保證始終釋放非托管資源。

大多數示例的問題是使用 IDisposable 的原因有多種,正確的實現因您使用它的原因而異。 例如,如果你直接包裝一個原生資源,你應該實現一個終結器,但如果你封裝另一個 IDisposable 類型,則終結器是不必要的,即使你仍然應該實現 IDisposable。 為了解決這個問題,我在我的博客 中深入寫了IDisposable 和 finalization ,描述了使用 IDisposable 的多種原因,以及出於不同原因的不同模式。

您可能只想閱讀我認為關於 IDisposable、終結器和垃圾收集的權威文章 Shawn Farkas 的CLR Inside Out:深入研究 IDisposable

這篇文章對這個主題幾乎沒有任何疑問。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM