1. 程式人生 > 程式設計 >.NET垃圾回收器原理及使用

.NET垃圾回收器原理及使用

.NET 應用程式中的垃圾回收器是什麼?

垃圾收集器只不過是 CLR 提供的一個功能,可幫助我們清理或銷燬未使用的託管物件。通過清理或銷燬這些未使用的託管物件,它基本上回收記憶體。

當DotNet應用程式執行時,它會建立多個物件,並且在給定時刻,應用程式可能不使用其中一些物件。

因此,對於這些物件,垃圾回收器作為後臺執行緒連續執行,並在特定的時間間隔時間,它會檢查是否有任何未使用的託管物件,以及它是否發現它只是清理這些物件並回收記憶體。

注:垃http://www.cppcns.com圾回收器將僅銷燬未使用的託管物件。它不清理非託管物件。

.NET垃圾回收器代數?

讓我們瞭解什麼是垃圾收集器代,它如何影響垃圾收集器的效能?

在.NET中,有三代。它們是第0代、第1代和第2代。

瞭解第0代、第1代和2代

假設您有一個名為 App1 的簡單應用程式。應用程式一啟動,就建立 5 個託管物件。

每當建立任何新物件(新物件)時,它們都會移動到稱為"第 0 代"http://www.cppcns.com;的儲存桶中。為了更好的理解,請看下圖所示:

.NET垃圾回收器原理及使用

我們知道垃圾收集器作為後臺執行緒連續執行,以檢查是否有任何未使用的託管物件,以便通過清理這些物件來回收記憶體。

現在,假設應用程式不需要兩個物件(Object1 和 Object2)。因此,垃圾回收器將銷燬這兩個物件(Object1 和 Object2),並回收第 0 代儲存桶中的記憶體。

但應用程式仍然需要其餘三個物件(Object3、Object4 和 Object5)。

因此,垃圾回收器不會清理這三個物件。因此,垃圾收集器將做的是,他這三個託管物件(Object3、Object4 和 Object5)將移動到第 1 代儲存桶,如下圖所示。

.NET垃圾回收器原理及使用

現在,假設您的應用程式又建立了兩個新物件(Object6 和 Object7)。作為新物件,應在第 0 代存儲桶中建立它們,如下圖所示。

.NET垃圾回收器原理及使用

現在,再次執行垃圾收集器,它涉及到第 0 代儲存桶和檢查使用的物件。假設應用程式未使用這兩個物件(Object6 和 Object7),因此它將刪除這兩個物件並回收記憶體。

現在,它轉到第 1 代儲存桶,並檢查哪些物件未使用。假設應用程式仍然需要 Object4 和 Object5,而不需要物件 3。

因此,垃圾收集器將做什麼,它將摧毀 Object3 並回收記憶體,以及它將 Objec4 和 Object5 移動到第 3 代儲存桶,如下圖所示。

.NET垃圾回收器原理及使用

什麼是幾代?

代不過是什麼,它們將定義物件在記憶體中保留的時間。現在,你想到的問題是,為什麼我們需要幾代?

為什麼我們需要幾代?

通常,當我們使用大型應用程式時,它們可以建立數千個物件。因此,每個物件,如果垃圾回收器去檢查他們真的是否需要,這是一個非常笨重的過程。

通過建立此類,如果第 2 代儲存桶中的物件意味著"垃圾收集器"將yOimXNAwA減少對此儲存桶的訪問。

原因是,如果物件移動到第 2 代,則意味著它將在記憶體中停留更多時間。沒有必要去檢查他們一遍又一遍。

因此,簡單地說,我們可以說第 0 代、第 1 代和 2 代有助於提高垃圾收集器的效能。第 0 代中的物件越好,效能越好,以最佳方式使用記憶體。

如何在類中使用解構函式,我們最終進入一個雙垃圾回收器迴圈?

垃圾收集器將只清理託管程式碼。換句話說,對於任何型別的非託管程式碼,要清理這些程式碼必須由非託管程式碼提供,垃圾回收器無法控制它們來清理記憶體。

例如,假設您在 VB6 中有一個名為 MyClass 的類,然後您必須公開一些函式,例如 CLeanUp(), 在該函式中,您必須編寫邏輯來清理非託管程式碼。

從DotNet程式碼中,您只需呼叫該方法 CLeanUp()即可啟動清理。這點,或要從其中呼叫清yOimXNAwA理的部分是類的解構函式。

這看起來是編寫清理程式碼的最佳地點。但是,在解構函式中編寫清理時,有一個與之相關的大問題。讓我們瞭解問題出在哪裡?

在類中定義解構函式時,垃圾收集器在處置物件之前,將轉到類中提出問題,您是否有解構函式,如果您有解構函式,然後將物件移動到下一代儲存桶。

換句話說,即使未使用解構函式本身,它也會清理具有解構函式的物件。因此,它將等待解構函式執行,然後它會去清理物件。因此,與第 0 代相比,第 1 代和第 2 代中的物件更多。

(示例)使用解構函式

建立一個控制檯應用程式,然後在程式類中複製並貼上以下程式碼。

.NET垃圾回收器原理及使用

注:如果在解構函式中編寫清理程式碼,則最終將在第 1 代和第 2 代中建立更多物件,這意味著您沒有正確使用記憶體。

如何克服上述問題?

通過使用所謂的最終處置模式可以解決此問題。

為了實現這一點,類應實現 IDisposable 介面,並提供 Dispose 方法的實現。在 Dispose 方法中,您需要為非託管物件編寫清理程式碼,最後需要呼叫 GC。通過將 true 作為輸入值傳遞來抑制無限化(true) 方法。

此方法告訴抑制任何型別的解構函式,然後去清理物件。為了更好的理解,請看下圖。

.NET垃圾回收器原理及使用

一旦您使用物件,然後您需要呼叫 Dispose 方法,以便雙垃圾回收器迴圈不會發生,如下所示。

.NET垃圾回收器原理及使用

完整的程式碼如下:

.NET垃圾回收器原理及使用

現在,想到的問題是,為什麼解構函式在那裡?原因是作為開發人員,您可能忘記在使用物件後呼叫 Dispose 方法。在這種情況下,解構函式將呼叫,它將去清理物件。

到此這篇關於.NET垃圾回收器原理及使用的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支援我們。