網站首頁 編程語言 正文
.NET 應用程序中的垃圾回收器是什么?
垃圾收集器只不過是 CLR 提供的一個功能,可幫助我們清理或銷毀未使用的托管對象。通過清理或銷毀這些未使用的托管對象,它基本上回收內存。
當DotNet應用程序運行時,它會創建多個對象,并且在給定時刻,應用程序可能不使用其中一些對象。
因此,對于這些對象,垃圾回收器作為后臺線程連續運行,并在特定的時間間隔時間,它會檢查是否有任何未使用的托管對象,以及它是否發現它只是清理這些對象并回收內存。
注:垃圾回收器將僅銷毀未使用的托管對象。它不清理非托管對象。
.NET垃圾回收器代數?
讓我們了解什么是垃圾收集器代,它如何影響垃圾收集器的性能?
在.NET中, 有三代。它們是第0代、第1代和第2代。
了解第0代、第1代和2代
假設您有一個名為 App1 的簡單應用程序。應用程序一啟動,就創建 5 個托管對象。
每當創建任何新對象(新對象)時,它們都會移動到稱為"第 0 代"的存儲桶中。為了更好的理解,請看下圖所示:
我們知道垃圾收集器作為后臺線程連續運行,以檢查是否有任何未使用的托管對象,以便通過清理這些對象來回收內存。
現在,假設應用程序不需要兩個對象(Object1 和 Object2)。因此,垃圾回收器將銷毀這兩個對象(Object1 和 Object2),并回收第 0 代存儲桶中的內存。
但應用程序仍然需要其余三個對象(Object3、Object4 和 Object5)。
因此,垃圾回收器不會清理這三個對象。因此,垃圾收集器將做的是,他這三個托管對象(Object3、Object4 和 Object5)將移動到第 1 代存儲桶,如下圖所示。
現在,假設您的應用程序又創建了兩個新對象(Object6 和 Object7)。作為新對象,應在第 0 代存儲桶中創建它們,如下圖所示。
現在,再次運行垃圾收集器,它涉及到第 0 代存儲桶和檢查使用的對象。假設應用程序未使用這兩個對象(Object6 和 Object7),因此它將刪除這兩個對象并回收內存。
現在,它轉到第 1 代存儲桶,并檢查哪些對象未使用。假設應用程序仍然需要 Object4 和 Object5,而不需要對象 3。
因此,垃圾收集器將做什么,它將摧毀 Object3 并回收內存,以及它將 Objec4 和 Object5 移動到第 3 代存儲桶,如下圖所示。
什么是幾代?
代不過是什么,它們將定義對象在內存中保留的時間。現在,你想到的問題是,為什么我們需要幾代?
為什么我們需要幾代?
通常,當我們使用大型應用程序時,它們可以創建數千個對象。因此,每個對象,如果垃圾回收器去檢查他們真的是否需要,這是一個非常笨重的過程。
通過創建此類,如果第 2 代存儲桶中的對象意味著"垃圾收集器"將減少對此存儲桶的訪問。
原因是,如果對象移動到第 2 代,則意味著它將在內存中停留更多時間。沒有必要去檢查他們一遍又一遍。
因此,簡單地說,我們可以說第 0 代、第 1 代和 2 代有助于提高垃圾收集器的性能。第 0 代中的對象越好,性能越好,以最佳方式使用內存。
如何在類中使用析構函數,我們最終進入一個雙垃圾回收器循環?
垃圾收集器將只清理托管代碼。換句話說,對于任何類型的非托管代碼,要清理這些代碼必須由非托管代碼提供,垃圾回收器無法控制它們來清理內存。
例如,假設您在 VB6 中有一個名為 MyClass 的類,然后您必須公開一些函數,例如 CLeanUp(), 在該函數中,您必須編寫邏輯來清理非托管代碼。
從DotNet代碼中,您只需調用該方法 CLeanUp()即可啟動清理。這點,或要從其中調用清理的部分是類的析構函數。
這看起來是編寫清理代碼的最佳地點。但是,在析構函數中編寫清理時,有一個與之相關的大問題。讓我們了解問題出在哪里?
在類中定義析構函數時,垃圾收集器在處置對象之前,將轉到類中提出問題,您是否有析構函數,如果您有析構函數,然后將對象移動到下一代存儲桶。
換句話說,即使未使用析構函數本身,它也會清理具有析構函數的對象。因此,它將等待析構函數運行,然后它會去清理對象。因此,與第 0 代相比,第 1 代和第 2 代中的對象更多。
(示例)使用析構函數
創建一個控制臺應用程序,然后在程序類中復制并粘貼以下代碼。
注:如果在析構函數中編寫清理代碼,則最終將在第 1 代和第 2 代中創建更多對象,這意味著您沒有正確使用內存。
如何克服上述問題?
通過使用所謂的最終處置模式可以解決此問題。
為了實現這一點,類應實現 IDisposable 接口,并提供 Dispose 方法的實現。在 Dispose 方法中,您需要為非托管對象編寫清理代碼,最后需要調用 GC。通過將 true 作為輸入值傳遞來抑制無限化(true) 方法。
此方法告訴抑制任何類型的析構函數,然后去清理對象。為了更好的理解,請看下圖。
一旦您使用對象,然后您需要調用 Dispose 方法,以便雙垃圾回收器循環不會發生,如下所示。
完整的代碼如下:
現在,想到的問題是,為什么析構函數在那里?原因是作為開發人員,您可能忘記在使用對象后調用 Dispose 方法。在這種情況下,析構函數將調用,它將去清理對象。
原文鏈接:https://www.cnblogs.com/zh7791/p/13704987.html
相關推薦
- 2022-07-15 Python?并行加速技巧分享_python
- 2022-08-03 python中time庫使用詳解_python
- 2024-07-15 SpringBoot使用itext導出pdf(含圖片和表格)
- 2022-05-03 基于docker部署skywalking實現全鏈路監控功能_docker
- 2023-05-31 Hadoop腳本遠程控制中SSH常見問題詳解_服務器其它
- 2022-07-24 C++深入刨析類與對象的使用_C 語言
- 2022-01-27 @ConfigurationProperties放在類上跟放在方法上有什么區別
- 2023-08-30 Linux下的scp 、rsync兩種命令同步文件
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支