網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
Reference
Why using finalizers is a bad idea
當(dāng)在一個(gè)類(lèi)中使用了另外一個(gè)實(shí)現(xiàn)了IDisposable
的類(lèi)作為一個(gè)成員屬性時(shí), 此時(shí)這個(gè)類(lèi)就有必要也去實(shí)現(xiàn)IDisposable接口, 以確保在合適的實(shí)際釋放非托管資源, 到底該如何正確的實(shí)現(xiàn)這個(gè)接口呢? 當(dāng)然這只是需要實(shí)現(xiàn)IDisposable接口其中一種情況
完整示例
示例的Foo
類(lèi)中包含了一個(gè)Stream
類(lèi)型的_stream
成員, 因此需要為Foo類(lèi)實(shí)現(xiàn)IDisposable模式
public class Foo : IDisposable { private bool _disposed; private readonly Stream? _stream; public Foo() { _stream = File.Create("1.txt", 2048); } ~Foo() { CleanupUnmanagedResources(); } private void CleanupUnmanagedResources() { if (_disposed) return; // 釋放非托管資源 _stream?.Dispose(); _disposed = true; } public void Dispose() { CleanupUnmanagedResources(); GC.SuppressFinalize(this); } }
為什么要實(shí)現(xiàn)Foo析構(gòu)函數(shù)
因?yàn)槿诵缘娜觞c(diǎn)(??)
哈哈, 其實(shí)因?yàn)槲覀冊(cè)谑褂?code>Foo時(shí)可能會(huì)忘記手動(dòng)調(diào)用其Dispose
方法, 這個(gè)時(shí)候如果沒(méi)有析構(gòu)函數(shù)的話(huà), 很可能導(dǎo)致資源永遠(yuǎn)得不到釋放最終釀成內(nèi)存泄漏的慘劇.
當(dāng)然啦, 在析構(gòu)函數(shù)中釋放非托管資源可能會(huì)給GC
帶來(lái)額外的開(kāi)銷(xiāo), 所以最好的做法是依然是使用using
塊保證能夠及時(shí)的調(diào)用Dispose方法, 這里使用析構(gòu)函數(shù)只是為了防止意外的發(fā)生. 至于為什么說(shuō)在析構(gòu)函數(shù)中釋放非托管資源會(huì)導(dǎo)致額外的GC
開(kāi)銷(xiāo)呢, 這涉及到GC回收過(guò)程,GC在處理包含析構(gòu)函數(shù)的類(lèi)時(shí)不會(huì)立即將此類(lèi)回收, 而是會(huì)被GC標(biāo)記為下一代, 這樣這個(gè)被標(biāo)記為下一代的類(lèi)只有在GC決定回收下一代的垃圾對(duì)象時(shí), 才會(huì)被真正回收掉, 這樣一來(lái)就會(huì)導(dǎo)致額外的內(nèi)存和性能開(kāi)銷(xiāo)了.
Dispose方法中為什么要調(diào)用GC.SuppressFinalize
GC.SuppressFinalize
方法可以告訴GC
不需要在調(diào)用此類(lèi)的析構(gòu)函數(shù)(Finalizers)了;
因?yàn)樵?code>Foo類(lèi)的析構(gòu)函數(shù)中調(diào)用了Foo.CleanupUnmanagedResources方法, 當(dāng)GC
回收此類(lèi)調(diào)用此類(lèi)析構(gòu)函數(shù)時(shí), 有可能會(huì)導(dǎo)致兩次調(diào)用Foo.CleanupUnmanagedResources(第一次是Dispose
方法中調(diào)用的)導(dǎo)致額外的開(kāi)銷(xiāo),
所以當(dāng)我們手動(dòng)調(diào)用了Foo.Dispose(通過(guò)是通過(guò)using
語(yǔ)法糖)后, 就需要告訴GC
, "你回收我的時(shí)候用不著調(diào)用我的析構(gòu)函數(shù)了, 該釋放的資源我早就釋放掉了已經(jīng)", 轉(zhuǎn)換成代碼就是GC.SuppressFinalize
原文鏈接:https://www.cnblogs.com/laggage/p/15734776.html
相關(guān)推薦
- 2022-07-13 ELK 日志分析系統(tǒng)的部署
- 2022-04-24 Android實(shí)現(xiàn)Neumorphism?UI控件_Android
- 2022-05-17 ubuntu Could NOT find CURL (missing: CURL_LIBRARY
- 2022-04-29 Go語(yǔ)言線(xiàn)程安全之互斥鎖與讀寫(xiě)鎖_Golang
- 2022-05-02 C/C++的各種字符串函數(shù)你知道幾個(gè)_C 語(yǔ)言
- 2022-05-13 Django-跨域問(wèn)題Csrf
- 2022-12-13 OpenCV視頻流C++多線(xiàn)程處理方法詳細(xì)分析_C 語(yǔ)言
- 2021-12-30 C++內(nèi)存管理之簡(jiǎn)易內(nèi)存池的實(shí)現(xiàn)_C 語(yǔ)言
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門(mén)
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支