阿里、蚂蚁、晟腾、中科加禾精彩分享 AI 基础设施洞见,现购票可享受 9 折优惠 |AICon 了解详情
写点什么

对 IDisposable 和静态分析的提议:DisposeUnused 属性

  • 2019-10-23
  • 本文字数:1734 字

    阅读完需:约 6 分钟

对IDisposable和静态分析的提议:DisposeUnused属性

当 .NET 初创的时候,关于IDisposable该如何使用存在一定的不确定性。结果,IDisposable的应用方式过于激进,许多种类的类都需要空的 Dispose 方法。这给静态分析工具带来了一些问题,它们无法将实际缺少Dispose调用与误报区分开来。


为了理解始末缘由,我们需要回过头看一下 CLR 早期的历史以及垃圾收集是如何运行的。最初,CLR 的目的在于是作为 Visual Basic 的新运行时,在 20 世纪 90 年代末 Visual Basic 是基于 COM 的。在 COM 模型下,对象会有一个引用计数。在引用创建和销毁的时候,引用计数会随之进行更新,如果计数变成零,对象就会被释放。这样的话,就形成了一个具有确定性的垃圾收集模型,在这种模型中,我们可以确切地知道该在什么时候清理资源。


引用方式的垃圾收集模型的最明显缺点就在于它很容易出现内存泄露。如果我们创建了一系列的对象,它们之间互相循环引用的话,每个对象都会让其他对象的引用计数无法降低到零,从而会出现内存泄露。在多线程环境中,它还会产生性能问题,因为在调整引用计数的时候,需要用到锁。


在开发的早期,微软决定采用标记-清理(mark-and-sweep)垃圾收集器来让 CLR 避免这些问题。随着 Java 的流行,这种方式在社区中得到了普遍的认可。但是,这种方式的 GC 并不能确定地释放资源,这使得它不适合用于数据库连接、文件处理和其他高度受限的资源。因此,IDisposable 应运而生。


与此同时,微软正在试验“组件”的理念。组件的概念从来没有被很好地定义。在这方面,有Component类,以及像IComponentIContainerISite这样的接口。在将近 20 年之后,文档中也只有一个很模糊的注释:“应用程序之间的对象共享”。其想法大概和 COM 类似,也就是某个应用可以直接与其他程序进行交互。但是,这并没有达到目的,所以被埋没在历史的故纸堆中了。


而在 Windows Forms 中,有一个不同的“组件”概念,它真正的意思是“可以放到表单/窗口(form/window)中的内容”。除了像文本框这样的实际 UI 元素之外,还包括添加了特定功能的对象,如计时器。这来自 VB 6 编程时代,当时几乎所有想使用的内容都必须要放到表单中。甚至数据库连接和命令也可以直接放到表单中。


这也就是为什么我们看到很多毫不相关的对象也标记成了IDisposable。像DataTableSqlCommand并没有要处理的非托管资源,但是在过去我们错误地认为最好将它们放到表单中,所以它们继承了Component类。而 Component 是 disposable 的,所以我们可以选择何时关闭代理对象。

静态分析

随着静态分析逐渐从高级工具变成了每个开发人员都该使用的工具,关于 disposable 对象不断增长的告警越来越成为一个问题。对于像SqlCommand这样短期存活的对象来说,这还不算太糟糕,因为可以很容易地使用 using 语句对其进行包装,而不需要考虑该语句实际上并没有执行任何操作。


DataTable这样的类就比较困难了。这是一个长期存活的对象,它所使用的地方可能距离创建它的地方非常远。除非设置为 suppressed 或禁用,否则静态分析工具将会报告 DataTable 和类似对象有未处理处理的告警和错误。

DisposeUnusedAttribute 提议

“最佳”方案是彻底移除所有无用的Dispose方法。但是,这并不是可行方案,因为这样会破坏向后的兼容性。


Edward Brey 提出了一个相当简单而优雅的解决方案。他建议创建一个DisposeUnused属性来屏蔽静态分析工具。子类不会继承此属性。


但是,这个设计也并非尽善尽美。一旦DisposeUnused用到了某个类上,移除它将会是破坏性的变更。对于 DataTable 来说,这并不是什么问题,不过,Stephen A. Imhoff 提供一个这样的样例。


这实际上会更糟糕,因为现在你可能会说“好的,忽略该契约,我就是这样声明的”,如果某个类型突然需要 dispose 某个资源的话(比如说,MemoryStream 要为大型数组或其他内容分配一个原生数组),那么你的消费者需要执行 dispose 操作,但是你之前却告诉人家不需要这样做……


另一个问题是你并不是总能知道变量里有什么。假设有一个类型为 Component 的变量。在编译时,我们无法判断放入变量的内容是否需要 dispose 处理。因此,更有意义的做法是只将DisposeUnused用到密闭类(sealed classed)中,这些类是无法子类化的。


原文链接:


A Proposal for IDisposable and Static Analysis: DisposeUnused Attribute


2019-10-23 08:00918

评论 1 条评论

发布
用户头像
对C#来说Attribute别翻译为属性更好些。记得王垠较早前就吐槽C#的这个了。
2019-10-23 17:52
回复
没有更多了
发现更多内容

数据中台必备的4个核心能力

阿泽🧸

数据中台 9月月更

【喜讯】亚信安慧通过CMMI5级认证

亚信AntDB数据库

AntDB AntDB数据库

软件测试 | 测试开发 | 环境问题还是测试的老大难?两个步骤轻松搞定

测吧(北京)科技有限公司

测试

【荣耀帐号服务】手把手教你快速web接入

荣耀开发者服务平台

前端 Web 服务器 安卓 honor

死熬三天三夜,阿里高工码出Java150K字面试宝典,却遭Github全面封杀

Java-fenn

Java 编程 面试 java面试 java;

两年工作经验,三面拼多多,最终获得offer!(面经总结)

Java-fenn

Java 编程 程序员 面试 java面试

史上最详细的一线大厂Mysql面试题详解

小小怪下士

MySQL 面试 java面试

肝完Alibaba这份面试通关宝典,今年的offer我拿手软了

Java-fenn

Java 程序员 面试 java面试 java;

蚂蚁智能容量团队推出 TMaestro 智能参数调节产品

TRaaS

产品 互联网技术

行业规模将达百亿,低代码是 “银弹” 还是 “鸡肋”?

SoFlu软件机器人

2022前端面试遇到的手写题总结

helloworld1024fd

JavaScript 前端

软件测试 | 测试开发 | 原来升职加薪的测试工程师都擅长做接口测试

测吧(北京)科技有限公司

测试

程序员该敬畏每一行代码?填好每一个坑才是!

小小怪下士

程序员 架构 java;

软件测试 | 测试开发 | 应用打包还是测试团队老大难问题?

测吧(北京)科技有限公司

测试

软件测试 | 测试开发 | 移动端App自动化之App控件定位

测吧(北京)科技有限公司

测试

MobTech 短信验证 Unity插件

MobTech袤博科技

ios android 短信验证

工作一年之后,这6个技术栈可以让你平均涨薪50%(涨薪篇)

Java-fenn

Java 编程 程序员 面试 java面试

名列前茅!亚信科技AntDB入围工信部电信行业数据库场景榜单

亚信AntDB数据库

AntDB AntDB数据库

大数据平台 CDP 中如何配置 hive 作业的 YARN 队列以确保SLA?

明哥的IT随笔

hadoop spark hive YARN CDP

Java面试笔试题大汇总一(最全+详细答案)

小小怪下士

大厂面试 java\ 面试真题 Java 面试题

阿里官方保姆级Java技术图谱发布,够学到元宵节了,赶紧收藏

Java-fenn

Java 程序员 技术 java面试 Java面经

阿里巴巴高并发架构到底多牛逼?是如何抗住淘宝双11亿级并发量?

Java-fenn

Java 编程 程序员 面试

分享面试阿里、京东、网易等大厂后的面经及面试心得—远程面试

Java-fenn

Java 程序员 技术 面试 java面试

解密数字时代 AI 加持之道,网易智企联合机器之心发布 AI 应用实践白皮书

网易云信

人工智能 音视频技术

什么是企业知识管理体系?它的基本原则是什么?我们又该怎样做?

Baklib

知识管理 知识 知识管理体系

软件测试 | 测试开发 | 精准化测试原理简介与实践探索

测吧(北京)科技有限公司

测试

阿里云物联网平台架构——业务架构类

阿里云AIoT

大数据 物联网平台 IoT 平台架构 设备管理

帮助中心就是在线版的产品使用说明书?并非如此!

Baklib

产品 产品经理 帮助中心 在线编辑 产品说明书

金三银四面试总结篇,汇总2022Java面试突击班后的面试小册

Java-fenn

Java 程序员 面试 java面试 java;

MASA MAUI Plugin 安卓蓝牙低功耗(二)蓝牙通讯

MASA技术团队

blazor MASA MAUI Xamarin MASA Blazor

什么是企业帮助中心?为什么要花钱建立?看这篇文章你就懂了!

Baklib

SaaS 企业 帮助中心 在线编辑

对IDisposable和静态分析的提议:DisposeUnused属性_语言 & 开发_Jonathan Allen_InfoQ精选文章