在.net中自动内存管理是有垃圾收集器来执行的,GC自动完成对托管堆的全权管理。
托管资源的回收:
1、如何回收
这部分主要是通过GC来回收,垃圾收集器正事通过根指针列表来获得托管堆中的对象图,其中定义了运用程序根引用的托管堆对象。当它启动时,它假设所有的对象都是可回收的,并开始遍历所有的根,将根引用的对象标记为可达对象图中,在遍历的过程中,如果根引用的对象还引用着其他对象,则该对象也被添加到可达对象图中。依次类推,递归遍历,将能找到所有可达对象,形成一个可达对象图。同时那些不可达对象被认为是可回收对象。(标记和清楚算法)
2、何时回收
(1)、内存不足溢出时,更确切的说是第0代对象充满时。
(2)、调用GC.Collect方法强制执行垃圾回收。
(3)、Windows 报告内存不足时,CLR讲强行执行垃圾回收。
(4)、CLR卸载AppDomain时,GC将对所有的代龄的对象执行垃圾回收。
(5)、其他情况,如物理内存不足等…
3、回收之后
GC执行垃圾回收之后,堆上将出现多个被收集对象的“空洞”,为避免托管堆中的碎步。会重新分配内存,压缩托管堆。在这个过程中肯定会影响GC回收的系统性能。而CLR垃圾收集器使用了Generation 的概念来提升性能。
非托管资源的清理:
常见的非托管资源有:数据库连接、文件句柄、网络连接、互斥体、COM对象、套接字、位图和GDI+对象等。
主要有两种方式:Finalize方法和Dispose方法。
对于这两种方法有如下的规则:
(1)、对于非托管资源的清理,Finalize由GC自动调用,而Dispose由开发者强制执行调用。
(2)、尽量避免使用Finalize方式来清理资源,必须实现时,也应一并实现Dispose方法。来提供显示的调用控制。
(3)、Finalize和Dispose方法,只能清理非托管资源,释放内存的工作仍由GC负责。
(4)、对象使用完毕应该立即释放其资源。最好显示调用Dispose方法来实现。