




全文预览已结束
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
C#.Net中的非托管代码清理这两天帮助其它项目组Review代码,发现有些地方实现了IDispose接口,同时也发现了一些关于IDispose的问题:1.A类型实现了IDispose接口,B类型里面含有A类型的字段,B类型没有实现IDispose接口2.一个类里面实现了Finalize终结器,同时也实现了IDispose接口,但在Dispose方法里面没有调用GC.SuppressFinalize(this)方法.下面我对以上两个问题分别分析一下,并提出解决方案。问题1如果A类型里面有非托管资源需要在实现的IDispose接口里面释放,由于B类型没有实现IDispose接口,B类型的使用者要想释放A类型的非托管资源并不方便.这样的话,就有可能忘记了释放A类型的非托管资源.解决方案:实现B类型的IDispose接口,在Dispose方法里面调用A类型的Dispose方法.这样,B类型的使用者在调用B类型Dispose的同时,就把A类型的Dispose也调用了.问题2在Dispose方法里面没有调用GC.SuppressFinalize(this)方法,会有什么问题呢,这样会导致垃圾回收器不能对 这个类型的对象及时回收. 当GC开始工作的时候,它首先将没有终结器的垃圾对象从内存中移除,有终结器的所有对象则添加到一个垃圾队列当中。GC会调用一个新线程来执行这些对象的 终结器。当终结器执行完毕后,这个对象会从队列中被移除。这个对象在队列中移除之后,当GC再次开始工作的时候,这个对象才能够被回收,所以有终结器的对 象会比没有的在内存中保留更长的时间。在后面我会对这里再详细的描述一下.解决方案:在Dispose方法中调用GC.SuppressFinalize(this)方法.这样的话,就不会把有终结器的对象则添加到垃圾队列当中.切入正题.net中,非托管代码清理有两种方式:Finalize方式和Dispose方式.Finalize方式:通过对自定义类型实现一个Finalize方法来释放非通过资源.从.net2.0开始,C#编译器不能对Finalize进行显示的调用和重写,必须使用析构函数来实现它.class AA()释放资源; 上面的代码就是通过Finalize方式来释放资源的跟C+用析构函数释放资源的代码很象.但是它实现方式和C+不同,因为它是由垃圾回收器来管理内存的.大家看到了,用Finalize方式释放非托管资源很简单,但是如果你了解了他的实现方式,你可能就不会选择用它来释放非托管资源.那Finalize方式在.net内部是如何实现的呢?当GC(垃圾回收器)开始工作的时候,它首先将没有终结器的垃圾对象从内存中移除,有终结器的所有对象则添加到一个终止化队列当中。GC会调用一个 新线程来执行这些对象的终结器。当终结器执行完毕后,这些对象会从队列中被移除。这时候由于这些对象在第一次检测到的时候没有被释放,它们将会进入第1代 对象,直到GC检测到第0代对象和第1代对象再次充满时,这时候GC才会把刚才那些对象释放掉,所以有终结器的对象会比没有的在内存中保留更长的时间。提示:垃圾回收器把托管堆中的对象分为3代,分别是0,1,2.一般分配为:0代约256K,1代约是2MB,第2代约是MB,代龄越高,容量就越 大,显然效率也就越低.首先被添加到托管堆中的对象被定为第0代,当第0代充满时,就会执行垃圾回收,未被回收的对象代领将提升1代.由于以上原因应该避免仅使用Finalize方式释放非托管资源.Dispose模式:在自定义类中实现IDispose接口,在接口中的Dispose方法中对非托管资源进行释放.闲话少说,上代码public class MyResourceRelease: IDisposable/ 保证资源只用释放一次private bool _alreadyDisposed = false;/ 用来判断释放资源的类别(托管和非托管)protected virtual void Dispose(bool isDisposing)if(_alreadyDisposed)return;if(isDisposing)/释放托管资源/释放非托管资源_alreadyDisposed = true; public void Dispose()Dispose(true); 上面的代码就是用Dispose方式释放资源的方法.因为上面自定义的Dispose(bool isDisposing)方法是virtual的,所以还可以在派生类里面对它进行overridepublic class MyDerivedResource: MyResourceReleaseprivate bool _disposed = false;protected override void Dispose(bool isDisposing)if(_disposed)return;try if(isDisposing)/释放托管资源/释放非托管资源_disposed = true;finallybase.Dispose(isDisposing); 这样可以确保释放继承链上所有对象的引用资源,在整个继承层次中传播Dispose模式.那用Dispose方式非托管资源就是最好的方法了吗?其实不然,因为类型实现了IDispose接口,这个类的使用者必须显示调用Dispose方法,或者在创建该类型对象的时候使用using关键 字,对于一些粗心的使用者可能会忘记调用Dispose方法,或者没有使用using关键字,这样就导致了非托管资源没有释放的后果.最佳方案同时实现终结器和Dispose方式.这样对于细心的使用者直接显示调用Dispose方法会提高垃圾回收的性能,对于粗心的使用者虽然忘记了调用Dispose方法,但也不至于使得非托管资源得不到释放.注意这里用到了GC. SuppressFinalize(this)方法.代码如下:public class MyResourceRelease: IDisposableMyResourceRelease()Dispose(false);/ 保证资源只用释放一次private bool _alreadyDisposed = false;/ 用来判断释放资源的类别(托管和非托管)protected virtual void Dispose(bool isDisposing)if(_alreadyDispos
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 黄冈营销活动策划方案
- 鸡西夜市活动方案
- 装饰公司交房会活动方案
- 功能食品考试题及答案
- 服务营销考试题及答案
- 美丽的南湖公园650字7篇
- 分析能力考试题及答案
- 防疫期间考试题及答案
- 项目预算与成本管控表格模板
- 动画概念考试题及答案
- 信息储存设备管理制度
- 人防机房管理制度
- 2025年轴流冷却风扇行业深度研究分析报告
- 《商法学》本科笔记
- 华能集团薪酬管理制度
- T/CIE 147-2022空间行波管加速寿命试验评估技术规范
- 系统性淀粉样变性护理
- 化工过程安全管理导则 (一)
- 借车给他人免责协议书
- 国家能源集团共享服务中心有限公司-企业报告(业主版)
- 《缺血性卒中脑细胞保护临床实践中国专家共识(2025年版)》解读
评论
0/150
提交评论