C#.Net中的非托管代码清理

C#.Net中的非托管代码清理

ID:38248124

大小:17.82 KB

页数:5页

时间:2019-06-06

C#.Net中的非托管代码清理_第1页
C#.Net中的非托管代码清理_第2页
C#.Net中的非托管代码清理_第3页
C#.Net中的非托管代码清理_第4页
C#.Net中的非托管代码清理_第5页
资源描述:

《C#.Net中的非托管代码清理》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库

1、C#.Net中的非托管代码清理这两天帮助其它项目组Review代码,发现有些地方实现了IDispose接口,同时也发现了一些关于IDispose的问题:1.A类型实现了IDispose接口,B类型里面含有A类型的字段,B类型没有实现IDispose接口2.一个类里面实现了Finalize终结器,同时也实现了IDispose接口,但在Dispose方法里面没有调用GC.SuppressFinalize(this)方法.下面我对以上两个问题分别分析一下,并提出解决方案。问题1如果A类型里面有非托管资源需要在实现的IDispose接口里面释放,由于B

2、类型没有实现IDispose接口,B类型的使用者要想释放A类型的非托管资源并不方便.这样的话,就有可能忘记了释放A类型的非托管资源.解决方案:实现B类型的IDispose接口,在Dispose方法里面调用A类型的Dispose方法.这样,B类型的使用者在调用B类型Dispose的同时,就把A类型的Dispose也调用了.问题2在Dispose方法里面没有调用GC.SuppressFinalize(this)方法,会有什么问题呢,这样会导致垃圾回收器不能对这个类型的对象及时回收.当GC开始工作的时候,它首先将没有终结器的垃圾对象从内存中移除,有终

3、结器的所有对象则添加到一个垃圾队列当中。GC会调用一个新线程来执行这些对象的终结器。当终结器执行完毕后,这个对象会从队列中被移除。这个对象在队列中移除之后,当GC再次开始工作的时候,这个对象才能够被回收,所以有终结器的对象会比没有的在内存中保留更长的时间。在后面我会对这里再详细的描述一下.解决方案:在Dispose方法中调用GC.SuppressFinalize(this)方法.这样的话,就不会把有终结器的对象则添加到垃圾队列当中.切入正题.net中,非托管代码清理有两种方式:Finalize方式和Dispose方式.Finalize方式:通过

4、对自定义类型实现一个Finalize方法来释放非通过资源.从.net2.0开始,C#编译器不能对Finalize进行显示的调用和重写,必须使用析构函数来实现它.classA{~A(){释放资源;}}上面的代码就是通过Finalize方式来释放资源的跟C++用析构函数释放资源的代码很象.但是它实现方式和C++不同,因为它是由垃圾回收器来管理内存的.大家看到了,用Finalize方式释放非托管资源很简单,但是如果你了解了他的实现方式,你可能就不会选择用它来释放非托管资源.那Finalize方式在.net内部是如何实现的呢?当GC(垃圾回收器)开始工

5、作的时候,它首先将没有终结器的垃圾对象从内存中移除,有终结器的所有对象则添加到一个终止化队列当中。GC会调用一个新线程来执行这些对象的终结器。当终结器执行完毕后,这些对象会从队列中被移除。这时候由于这些对象在第一次检测到的时候没有被释放,它们将会进入第1代对象,直到GC检测到第0代对象和第1代对象再次充满时,这时候GC才会把刚才那些对象释放掉,所以有终结器的对象会比没有的在内存中保留更长的时间。提示:垃圾回收器把托管堆中的对象分为3代,分别是0,1,2.一般分配为:0代约256K,1代约是2MB,第2代约是MB,代龄越高,容量就越大,显然效率也

6、就越低.首先被添加到托管堆中的对象被定为第0代,当第0代充满时,就会执行垃圾回收,未被回收的对象代领将提升1代.由于以上原因应该避免仅使用Finalize方式释放非托管资源.Dispose模式:在自定义类中实现IDispose接口,在接口中的Dispose方法中对非托管资源进行释放.闲话少说,上代码publicclassMyResourceRelease:IDisposable{///保证资源只用释放一次privatebool_alreadyDisposed=false;///用来判断释放资源的类别(托管和非托管)protectedvirtua

7、lvoidDispose(boolisDisposing){if(_alreadyDisposed){return;}if(isDisposing){//释放托管资源}//释放非托管资源_alreadyDisposed=true;}publicvoidDispose(){Dispose(true);}}上面的代码就是用Dispose方式释放资源的方法.因为上面自定义的Dispose(boolisDisposing)方法是virtual的,所以还可以在派生类里面对它进行overridepublicclassMyDerivedResource:My

8、ResourceRelease{privatebool_disposed=false;protectedoverridevoidDispose(boo

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。