網站首頁 編程語言 正文
Reference
Why using finalizers is a bad idea
當在一個類中使用了另外一個實現了IDisposable
的類作為一個成員屬性時, 此時這個類就有必要也去實現IDisposable接口, 以確保在合適的實際釋放非托管資源, 到底該如何正確的實現這個接口呢? 當然這只是需要實現IDisposable接口其中一種情況
完整示例
示例的Foo
類中包含了一個Stream
類型的_stream
成員, 因此需要為Foo類實現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); } }
為什么要實現Foo析構函數
因為人性的弱點(?)
哈哈, 其實因為我們在使用Foo
時可能會忘記手動調用其Dispose
方法, 這個時候如果沒有析構函數的話, 很可能導致資源永遠得不到釋放最終釀成內存泄漏的慘劇.
當然啦, 在析構函數中釋放非托管資源可能會給GC
帶來額外的開銷, 所以最好的做法是依然是使用using
塊保證能夠及時的調用Dispose方法, 這里使用析構函數只是為了防止意外的發生. 至于為什么說在析構函數中釋放非托管資源會導致額外的GC
開銷呢, 這涉及到GC回收過程,GC在處理包含析構函數的類時不會立即將此類回收, 而是會被GC標記為下一代, 這樣這個被標記為下一代的類只有在GC決定回收下一代的垃圾對象時, 才會被真正回收掉, 這樣一來就會導致額外的內存和性能開銷了.
Dispose方法中為什么要調用GC.SuppressFinalize
GC.SuppressFinalize
方法可以告訴GC
不需要在調用此類的析構函數(Finalizers)了;
因為在Foo
類的析構函數中調用了Foo.CleanupUnmanagedResources方法, 當GC
回收此類調用此類析構函數時, 有可能會導致兩次調用Foo.CleanupUnmanagedResources(第一次是Dispose
方法中調用的)導致額外的開銷,
所以當我們手動調用了Foo.Dispose(通過是通過using
語法糖)后, 就需要告訴GC
, "你回收我的時候用不著調用我的析構函數了, 該釋放的資源我早就釋放掉了已經", 轉換成代碼就是GC.SuppressFinalize
原文鏈接:https://www.cnblogs.com/laggage/p/15734776.html
相關推薦
- 2022-12-24 python項目運行導致內存越來越大的原因詳析_python
- 2022-06-06 layui 日期格式不正確(date、datetime)區別
- 2024-03-14 docker創建自定義網絡
- 2022-12-03 Golang基于sync.Once實現單例的操作代碼_Golang
- 2022-09-19 Redis緩存穿透/擊穿工具類的封裝_Redis
- 2022-05-25 Python小游戲實現實例之接蘋果_python
- 2022-11-04 SQL?Server還原完整備份和差異備份的操作過程_MsSql
- 2022-06-04 CZGL.ProcessMetrics監控.NET應用_實用技巧
- 最近更新
-
- 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同步修改后的遠程分支