详解IDisposable和Finalize的意义

简介:

本文主要讨论IDisposable和Finalize如何释放资源,以及微软提供并推荐的一个标准IDisposable编程模式。

本文写的通俗易懂,如果你还看不懂,就自己去反省一下为什么自己水平这么烂....


IDisposable接口主要提供一个Dispose方法,该方法用来释放资源,准确的说是用来释放非托管资源。理论上不是必须有 IDisposable 接口,你也能自己设计出一个释放非托管资源的方法,但是使用这个接口的话,大家都统一使用,比较好理解,并且使用这个接口的类,可以使用using这种语法糖。

Finalize其实就是析构函数,学过C++的都知道啥叫析构函数,C#也一样。你必须显式的定义一个析构函数,这样,C#编译器才会生成一个Finalize方法。可以使用工具查看IL代码得到验证,IL代码显示了Finalize方法的结果是一个try finally结果,和using类似。

既然 IDisposable和Finalize都是回收非托管资源,那么为什么微软要提供雷同的功能呢?


IDisposable和Finalize确实雷同,但也有一些差别。

Dispose方法是主动调用(使用using也算主动调用),主动释放非托管资源。而析构函数是由GC回收托管资源的时候调用,因此何时调用是不可掌控的。因此完全依靠析构函数会导致出现非托管资源迟迟得不到释放,如果资源过大,堆积在内存增加内存泄露的风险。


也许有人会说,那我只要把非托管资源放到Dispose方法中,保证释放,那就不需要使用析构函数了。完全正确。但是前提是你保证释放了。假设你写了一个框架或者类库,其中使用了非托管资源,而且也必须显式调用Dispose才能释放掉。但是,假如某个2B程序员使用这个类库,他根本没考虑要手动释放资源,因此他在用你的类库后,发现经常内存动不动就满了或者连接数满了,然后就开骂你是各种2B,写的东西是一坨垃圾。


为了避免背这个黑锅,也避免被2B骂成2B,你可以依靠析构函数设置一个底线,就是在GC启动的时候也能触发一个动作去回收非托管资源,你就需要在Finalize中去做这些事情。


因此对于释放非托管资源,可以归结2个要点:

1,只实现Dispose方法,无法保证人人都会调用此方法,万一没调用,背黑锅的就是你。

2,只实现析构函数,可以保证回收非托管资源,但是无法掌握释放时机,因为GC何时触发析构函数是不确定的。运气不好的话,非托管资源长时间都得不到释放。

只有这2个方法同时使用,才能最大限度的释放非托管资源。因此微软提出了一个 IDisposable 编程模式。具体模式参考http://msdn.microsoft.com/en-us/library/system.idisposable.aspx



在这模式中:

如果用户调用了Dispose,则会调用Dispose(true),以此表示释放托管资源和非托管资源。并且注意GC.SuppressFinalize();方法很有必要,这个方法是压制了析构函数的调用,因为非托管资源以及释放,析构函数中的释放语句也没有必要执行了,一不小心可能还会导致错误。


如果用户没有调用Dispose,那么GC在回收资源的时候,会触发析构函数,注意,此时传入的Dispose(false);因为析构函数只负责释放非托管资源,不建议用析构函数去释放托管资源,因为析构函数调用时机是不确定的,托管资源很可能已经被释放掉了,从而导致一些异常的发生。

采用微软的模式简单有效,当然你也可以实现自己的模式,这就看各人需要了。



















本文转自cnn23711151CTO博客,原文链接: http://blog.51cto.com/cnn237111/1246402,如需转载请自行联系原作者


目录
打赏
0
1
1
0
143
分享
相关文章
kde
|
5天前
|
Docker镜像加速指南:手把手教你配置国内镜像源
配置国内镜像源可大幅提升 Docker 拉取速度,解决访问 Docker Hub 缓慢问题。本文详解 Linux、Docker Desktop 配置方法,并提供测速对比与常见问题解答,附最新可用镜像源列表,助力高效开发部署。
kde
3155 8
国内如何安装和使用 Claude Code镜像教程 - Windows 用户篇
国内如何安装和使用 Claude Code镜像教程 - Windows 用户篇
573 0
Dify MCP 保姆级教程来了!
大语言模型,例如 DeepSeek,如果不能联网、不能操作外部工具,只能是聊天机器人。除了聊天没什么可做的。
843 9
2025年最新版最细致Maven安装与配置指南(任何版本都可以依据本文章配置)
本文详细介绍了Maven的项目管理工具特性、安装步骤和配置方法。主要内容包括: Maven概述:解释Maven作为基于POM的构建工具,具备依赖管理、构建生命周期和仓库管理等功能。 安装步骤: 从官网下载最新版本 解压到指定目录 创建本地仓库文件夹 关键配置: 修改settings.xml文件 配置阿里云和清华大学镜像仓库以加速依赖下载 设置本地仓库路径 附加说明:包含详细的配置示例和截图指导,适用于各种操作系统环境。 本文提供了完整的Maven安装和配置
2025年最新版最细致Maven安装与配置指南(任何版本都可以依据本文章配置)
【保姆级图文详解】大模型、Spring AI编程调用大模型
【保姆级图文详解】大模型、Spring AI编程调用大模型
361 7
【保姆级图文详解】大模型、Spring AI编程调用大模型
Excel数据治理新思路:引入智能体实现自动纠错【Python+Agent】
本文介绍如何利用智能体与Python代码批量处理Excel中的脏数据,解决人工录入导致的格式混乱、逻辑错误等问题。通过构建具备数据校验、异常标记及自动修正功能的系统,将数小时的人工核查任务缩短至分钟级,大幅提升数据一致性和办公效率。
DeepSeek R1+Open WebUI实现本地知识库的搭建和局域网访问
本文介绍了使用 DeepSeek R1 和 Open WebUI 搭建本地知识库的详细步骤与注意事项,涵盖核心组件介绍、硬件与软件准备、模型部署、知识库构建及问答功能实现等内容,适用于本地文档存储、向量化与检索增强生成(RAG)场景的应用开发。
371 0
让AI时代的卓越架构触手可及,阿里云技术解决方案开放免费试用
阿里云推出基于场景的解决方案免费试用活动,新老用户均可领取100点试用点,完成部署还可再领最高100点,相当于一年可获得最高200元云资源。覆盖AI、大数据、互联网应用开发等多个领域,支持热门场景如DeepSeek部署、模型微调等,助力企业和开发者快速验证方案并上云。
306 22
让AI时代的卓越架构触手可及,阿里云技术解决方案开放免费试用
FLUX.1 Kontext 的全生态教程来啦!AIGC专区在线试玩!
Flux.1 Kontext [dev] 开源模型大家都用上了吗?小编汇总了3个使用教程,打包送上!
426 1
AI助理
登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问

你好,我是AI助理

可以解答问题、推荐解决方案等