.Net的内存管理,非托管资源的处理原则
2011-10-28 11:24
323 查看
在.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,这样内存管理方式就类似于托管资源了。
非托管资源(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,这样内存管理方式就类似于托管资源了。
相关文章推荐
- .NET对象的创建、垃圾回收、非托管资源的手动处理
- .NET进行异常处理时的原则注意事项
- .NET对象的创建、垃圾回收、非托管资源的手动处理
- .NET互操作性入门系列(三):平台调用中的数据封送处理
- Java异常处理原则
- .net 错误处理
- 请求WebMethod,Ajax处理更加简练【注:此方法需要在.net 3.5版本以上】
- .net错误处理机制
- C++第六周任务一【任务1】下面的程序存在编译错误。有两种方法可以修改,请给出这两种修改方案,在报告中说明你倾向于用哪一种?为什么?处理此类问题的原则是什么?
- .NET的堆和栈04,对托管和非托管资源的垃圾回收以及内存分配
- .NET使用一般处理程序生成验证码!
- .net前端后台两种方式处理树形结构(tree)
- 对于.Net软件 用Reflector 常看显示 \u**** 的处理办法
- Silverlight 2.5D RPG游戏“.NET技术”技巧与特效处理:(十二)魔法系统
- Redis 内存管理与事件处理
- Microsoft NLa“.NET研究”yerApp案例理论与实践 - 多层架构与应用系统设计原则
- 有关defunct进程(僵尸进程)的处理原则
- .NET开发中的事务处理大比拼
- .NET 2.0 中的自定义配置处理
- .NET调试处理命令行参数