基础才是重中之重~对象的生与死

简介:

为何要写

之所以写这篇文章,完全是因为学生们在实际开发中遇到的问题,一个对象占用的内存空间总不被释放,导致系统内存不断攀升,其最主要原因是我们对“对象的生与死”不清楚,或者从来没有认真去考虑过这件事,确实一个对象在被声音,初始化,使用或者最后被系统回收,整个的过程与我们关系确实不大,我们开发人员直接用就行了,对于C#这种托管语言你没必要去自己回收它,但有时,我们多了解一点系统的回收机制,对我们的程序还是很有好处的。

对象的种类(根据作用域)

1 类对象,静态对象,使用static修饰符进行声明,作用域为整个类(所有实体公有),当你的程序运行期间它一直不会被回收,直到你的进程结束(所以使用它要注册,大数据一般不用类对象存储)

2 类级别的实例对象,它定义在类里,方法体外面,作用域为整个类的当前实例,它的回收时机我们无法确定,当然你可以手动进行  GC.Collect()来马上释放它,否则由系统的垃圾回收机制管理它

3 方法级别的实例对象,局部对象,它定义在方法内部,作用域为当前方法体,方法执行完成后,自动释放

代码中的实验

    public class Product
    {
        ~Product()
        {
            Logger.LoggerFactory.Instance.Logger_Info("Product对象已经被释放");
        }
        public int ID { get; set; }
        public string Name { get; set; }
    }

    public class ProductConfig
    {
        ~ProductConfig()
        {
            Logger.LoggerFactory.Instance.Logger_Info("ProductConfig对象已经被释放");
        }
        public int ID { get; set; }
        public string Name { get; set; }
    }
        /// <summary>
        /// 类级别的
        /// </summary>
        ProductConfig productConfig = new ProductConfig();
        public ActionResult Create()
        {
            /// <summary>
            /// 实例成员,方法体里
            /// </summary>
            Product product = new Product();
            GC.Collect();//清除全局实例成员,否则全局实例对象将不会马上清楚,它会等待垃圾回收
            return View();
        }

上面代码在执行后,会写入日志文件,由于在方法里使用了GC.Collect()方法,这时全局实例对象ProductConfig将会在方法执行后被释放,如果不加这个方法,那么ProductConfig何时释放,我们是不知道的。

Dispose模式

对上面的操作是我们刻意去进行的,意思就是让大家看到,对象何时会被释放,而对象在被释放后,会执行类的析构方法(~开头的),它在C#里很少被使用,或者我们很少关注它,因为你不去实现它,系统垃圾回收结束后也会去调用它,这是对于托管资源说的,我们在C#这个开发语言里,有时也会涉及到使用一些“非托管”资源,比如数据库连接,网络通讯,文件访问等等,它们是不受当前Frameworks CLR控制的,或者说CLR也控制不了它,因为它已经脱离了当前应用程序,这也算是合情合理,这时,这些非托管资源会实现自己的“资源释放”方法,好Dispose,大家如果有心的话,都会发现像文件,SQL连接,socket,Tcp等对象,都有Dispose方法,它的意思就是释放当前对象,而我们在使用它们时,如何把非托管与托管对象结合起来,一起把对象释放呢,这就是现在要说的Dispose模式

   /// <summary>
    /// 实现IDisposable,对非托管系统进行资源回收
    /// 作者:仓储大叔
    /// </summary>
    public abstract class DisposableBase : IDisposable
    {
        /// <summary>
        /// 标准Dispose,外界可以直接调用它
        /// </summary>
        public void Dispose()
        {
            Logger.LoggerFactory.Instance.Logger_Debug("Dispose");

            this.Dispose(true);////释放托管资源
            GC.SuppressFinalize(this);//请求系统不要调用指定对象的终结器. //该方法在对象头中设置一个位,系统在调用终结器时将检查这个位
        }

        private void Dispose(bool disposing)
        {
            if (!_isDisposed)//_isDisposed为false表示没有进行手动dispose
            {
                //清理托管资源和清理非托管资源
                Finalize(disposing);
            }
            Logger.LoggerFactory.Instance.Logger_Debug("Dispose complete!");
            _isDisposed = true;
        }

        /// <summary>
        /// 由子类自己去实现自己的Dispose逻辑(清理托管和非托管资源)
        /// </summary>
        /// <param name="disposing"></param>
        protected abstract void Finalize(bool disposing);

        private bool _isDisposed;

        /// <summary>
        /// 是否完成了资源的释放
        /// </summary>
        public bool IsDisposed
        {
            get { return this._isDisposed; }
        }
        /// <summary>
        /// 析构方法-在类被释放前被执行
        /// </summary>
        ~DisposableBase()
        {
            Logger.LoggerFactory.Instance.Logger_Debug("析构方法");

            //执行到这里,托管资源已经被释放
            this.Dispose(false);//释放非托管资源,托管资源由终极器自己完成了
        }
    }

使用它

  public class ZzlTools : DisposableBase
    {

        protected override void Finalize(bool disposing)
        {
            if (!disposing)
            {
                //清除托管
            }
            //清理非托管
        }
    }

通过大叔整理的Dispose基类,我们可以看到,外界的对象只要实现Finalize方法即可,把自己需要释放的对象写在Finalize里就行了,简单!

最后,和大家分享我的一个经验,学习基础知识,就像修炼内功,我们一定要打好根基,才能更上一层楼!

谢谢阅读!

本文转自博客园张占岭(仓储大叔)的博客,原文链接:基础才是重中之重~对象的生与死,如需转载请自行联系原博主。

目录
相关文章
|
7月前
|
存储 搜索推荐
知识体系化的必要性及构建通用体系的方法
知识体系化的必要性及构建通用体系的方法
266 0
|
11月前
|
数据采集 存储 人工智能
谈谈如何构建有效的数据供应链
谈谈如何构建有效的数据供应链
|
12月前
|
机器学习/深度学习 人工智能 机器人
在企业内部发现IT人才的5种方法
在企业内部发现IT人才的5种方法
|
存储 SQL 人工智能
谈谈企业如何构建现代数据平台
数据平台是一组集成的技术,它们共同满足组织的端到端数据需求。
谈谈企业如何构建现代数据平台
|
搜索推荐 数据挖掘 大数据
谈谈数据驱动和数据导向方法的选择
是数据做出了决定,还是你用数据帮助做出了决定?两者的选择将改变公司与数据的关系。
|
数据采集 数据管理 数据挖掘
谈谈现代环境下的数据治理之路
自助数据消费者的需求,敏捷实践的价值与数据治理的传统实践之间存在着天然的瓶颈。
谈谈现代环境下的数据治理之路
|
机器学习/深度学习 人工智能 算法
谈谈从分析到行动看数据驱动和数据信息的区别
近年来,“数据驱动”这个术语已经被广泛使用,很多人谈论要成为一个数据驱动的组织。
谈谈从分析到行动看数据驱动和数据信息的区别
|
数据采集 存储 运维
谈谈企业数据治理的几点思考
根据企业的特点,数据划分为以下三种类型:主数据、交易数据、指标(分析型)数据。
谈谈企业数据治理的几点思考
|
数据采集 存储 监控
谈谈如何制定完整动态的数据治理框架
作为一个概念,数据治理已经存在了几十年。到了20世纪80年代,计算机的繁荣导致了旨在处理数据质量和元数据管理等问题的技术的出现,这些技术通常以部门为基础,以支持数据库营销或数据仓库工作。
谈谈如何制定完整动态的数据治理框架
|
敏捷开发 自然语言处理 数据可视化
实例化需求不可或缺的精益、敏捷需求实践 | 方法案例二
本文的主旨是帮助大家,第一:理解实例化需求,介绍实例化需求的 Why 和 What;第二:实施实例化需求,介绍实例化需求的 Who,When 和 How。如此 4W1H,帮助大家掌握这一高效的精益和敏捷需求实践,并落实验收测试驱动开发(ATDD)方法。
1440 0
实例化需求不可或缺的精益、敏捷需求实践 | 方法案例二