.Net的内存管理,非托管资源的处理原则

来源:互联网 发布:全球网络摄像头 编辑:程序博客网 时间:2024/06/05 18:01


       在.Net框架中,内存的回收是由垃圾回收器去管理的,所以我们可以尽情的去申请内存资源,而不必考虑释放。但有些情况比较特别,对于非托管资源,我们最好自己考虑去释放。

非托管资源(Unmanaged Resource)是dot Net的一个概念,指诸如包装操作系统资源的一类对象,例如文件,窗口或网络连接

这里列举几种常见的非托管资源:画笔、流对象、组件对象等等资源(OdbcDataReader,OleDBDataReader,Pen,Regex,Socket,StreamWriter,ApplicationContext,Brush,Component,ComponentDesigner,Container,Context,Cursor,FileStream,Font,Icon,Image,Matrix,Timer,Tooltip);

为什么最好自己去释放?

首先得说说垃圾回收的过程,当引用类型的变量出了作用域以后,它不会立刻释放堆上的内存。当垃圾回收器觉得内存紧张的时候,才会进行内存回收。在内存回收之前,他会执行这个对象的Finalize方法。因此这些常见的非托管资源类通常会在自己的Finalize自己释放操作系统资源,如数据库连接。

貌似内存最终都会自己回收系统资源,对这些非托管资源我们完全可以不顾忌,但问题来了:对于数据库连接,一个连接池的连接数有限制,比如5个,在程序结束之后,垃圾回收之前,我们申请的连接对象会一直占用这个连接,导致数据库服务能力大降低。

对于这种问题,我们的解决方法是在代码运行结束之后,主动的去释放托管资源。如果SqlConnection这个对象,我们在操作完数据库以后,执行一下SqlConnection.Dispose(),他们自己会主动清除内存上的所有资源。问题得解。

不过,对于数据库连接,这是一个非常常用的操作,我们一旦创建了这个类,就不希望他再消失。免得每次用的时候都得重新申请一次内存。但我们对希望当操作完数据库以后,释放数据库连接这种非托管资源。那好,我们可以执行SqlConnection.Colose()这个方法。这样我们可以一直使用SqlConnecton这个对象,且不会长期占用一个数据库连接。当我们需要重新操作数据库时,可以用SqlConnection.Open来打开连接。

简单总结一下

1.      对于Finalize大家完全可以不知道有这么个东西。

2.      对于服务能力有限且常常会用到的非拖管资源,如果数据库连接,Ftp连接,我们最好在使用前open(),用完以后执行一下close。

3.      对于其它非拖管资源,尽量dispose一下,当然也可以只执行close,这样内存管理方式就类似于托管资源了。

 

原创粉丝点击