1、C#几乎所有对象都为托管对象,不同点是有的对象封装了非托管资源。
2、C#大部分对象在进行垃圾回收时都可以回收,包括非托管资源,因为非托管资源都已经通过C#类进行了封装,会将非托管资源的释放放在析构函数中,同时会实现IDipose接口。
3、IDipose作用是可以通过using手动提前释放,节约宝贵的资源。
4、在C#中,凡是继承了IDisposable接口的类,都可以使用using语句,从而在超出作用域后,让系统自动调用Dispose()方法。 一个资源安全的类,都实现了IDisposable接口和析构函数。提供手动释放资源和系统自动释放资源的双保险。
5、类似FileStream,会同时实现IDipose,及定义~FileStream(),~FileStream()作用是使用者没有调用IDipose,在GC回收时再回收非托管资源,否则非托管资源只有在程序停止之后才会释放。
析构函数只能由垃圾回收器调用。Despose()方法只能由类的使用者调用。
总结区分托管资源和非托管资源
(1)托管资源一般是指被CLR控制的内存资源,这些资源的管理可以由CLR来控制,例如程序中分配的对象,作用域内的变量等。
(2)非托管资源是CLR不能控制或者管理的部分,这些资源有很多,比如文件流,数据库的连接,系统的窗口句柄,打印机资源 等,这些资源一般情况下不存在于Heap(内存中用于存储对象实例的地方)中。
托管资源:从文字上看就是托付给别人管理,就像.NET的CLR,java的jvm
例子:
public class SourceManager : IDisposable { private bool disposed = false; //非托管资源 private IntPtr handle; //托管资源 FileStream fs = null; public SourceManager() { } //由垃圾回收器调用,释放非托管资源 ~SourceManager() { //GC调用,终结 Dispose(false);// 释放非托管资源 } //实现接口方法 //由类的使用者,在外部显示调用,释放类资源 public void Dispose() { Dispose(true);// 释放托管和非托管资源 //将对象从垃圾回收器链表中移除, // 从而在垃圾回收器工作时,只释放托管资源,而不执行此对象的析构函数 GC.SuppressFinalize(this); } //参数为true表示释放所有资源,只能由使用者调用 //参数为false表示释放非托管资源,只能由垃圾回收器自动调用 //如果子类有自己的非托管资源,可以重载这个函数,添加自己的非托管资源的释放 //但是要记住,重载此函数必须保证调用基类的版本,以保证基类的资源正常释放 protected virtual void Dispose(bool disposing) { // 如果资源未释放 这个判断主要用了防止对象被多次释放 if (!this.disposed) { if (disposing && fs != null) { // 释放托管资源 fs.Dispose(); } //释放非托管资源 //... handle = IntPtr.Zero; disposed = true; // 标识此对象已释放 } } }