• C# 托管非托管资源释放


    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; // 标识此对象已释放
            }
    
        }
    }
  • 相关阅读:
    06-tree Shaking
    05-babel-解析高级js语法+polyfill按需注入
    Symbol.iterator
    回调
    finally
    then的参数
    通过简单例子看Promise(一)
    作为Promise构造函数参数的函数
    resolved和rejected
    resolve和reject
  • 原文地址:https://www.cnblogs.com/valor-xh/p/6732384.html
Copyright © 2020-2023  润新知