c#内存管理,垃圾回收和资源释放

<1>关于虚拟内存的概念

Windows使用一个虚拟寻址系统,该系统把程序可用的内存地址映射到硬件内存中的实际地址上去,这些任务完全由windows后台管理,其实际结果是32位处理机上的每个进程都可以使用4GB内存,这个内存称为虚拟内存;

<2>栈和堆的概念

栈:在进程的虚拟内存中,有一个区域称为栈,栈存储的是值数据类型,在程序第一次开始运行的时候,栈指针指向为栈保留的内存块的末尾,栈实际上是从高地址内存向低地址内存分配的,在释放变量时,恰好相反;

堆:托管堆是虚拟内存的另一个内存区域,堆的内存是由下往上分配的,这一点与栈不同,例如实例化一个类,这个对象的引用信息存储在栈上,这个对象的实例信息保存在堆上,当引用变量超出作用域后,它会从栈中删除,但是引用对象的数据仍然会保留在堆中,直到程序结束或者垃圾回收器删除它为止,而只有在该数据不再被任何变量引用的时候,它才会被删除;

<3>垃圾回收

垃圾回收器运行时,它会降低应用程序的性能,因为垃圾回收器完成其任务之前,应用程序不可能继续执行,所以垃圾回收器采用的是世代垃圾回收器;提高垃圾回收器的另外一个方法是架构处理堆上较大对象的方式,较大对象有自己的托管堆,而不是在主堆上;

<4>释放非托管的资源

垃圾回收器不知道如何释放非托管的资源(例如文件句柄,网络连接和数据库连接),通常有两种方式来释放非托管的资源:一是声明一个析构函数(或终结器),作为类的一个成员,二是在类中实现System.IDisposable接口;

<5>析构函数

c#析构函数有两个缺点:一是由于c#采用了垃圾回收器的工作方式,无法确定析构函数何时执行,所以不能再析构函数中放置需要在某一时刻运行的代码,也不应该使用能以任意顺序对不同类的实例调用的析构函数,二是c#析构函数的实现会延迟对象从内存中删除的时间,没有析构函数的对象会在垃圾回收器的一次处理中从内存中删除,但有析构函数的对象需要两次才能够删除,如果频繁的使用析构函数,而且使用它们执行长时间的清理任务,对性能的影响就会非常的显著;

<6>IDisposable接口

在c#中,推荐使用System.IDisposable接口替代析构函数,IDisposable接口定义了一种模式,该模式为释放非托管的资源提供了确切的机制,并避免产生析构函数固有的与垃圾回收器相关的问题,它声明了一个Dispose()方法,Dispose()方法显式的释放由对象直接使用的所有非托管资源;但是要考虑到一个问题就是如果程序中间出现异常可能会出现不执行这个方法的情况,这时要放在try...finally块中,这样又会使代码看起来很混乱,这时可以放在using里面;

posted on 2016-10-24 21:05  insanewang  阅读(564)  评论(0编辑  收藏  举报