.net中对象占用资源的回收

简介:     一,使用Finalizer析构器                1,使用了Finalizer析构器的对象如何被回收?                           在类中定义了析构器的对象将会被移动到一个专门的队列中,这个队列将作为它的应用程序根,而使队列中的对象存活的更久一点,在对象上面调用完析构函数后,对象才会从队列中清理掉。




    一,使用Finalizer析构器


               1,使用了Finalizer析构器的对象如何被回收?


                          在类中定义了析构器的对象将会被移动到一个专门的队列中,这个队列将作为它的应用程序根,而使队列中的对象存活的更久一点,在对象上面调用完析构函数后,对象才会从队列中清理掉。


               2,使用示例

                         

<span style="font-family:Microsoft YaHei;"> class Program
    {
        static void Main(string[] args)
        {
            Cup cup = new Cup() { 
            
                CupName="lhc的小杯子~~~~"
            };

        }
    }

    public class Cup {
        public string CupName { get; set; }

        ~Cup() { 
           //此处放置析构代码:对比C++的析构函数,感觉意思是一样的

                //这里放置释放资源的代码
            Console.WriteLine("小杯子已被打碎~~~~么么哒~~~~~");       
        }
    
    }</span>

            

                感觉从语法上很像C++,嘿嘿~



            3,使用析构器该注意哪些问题?

                    

               1,开发这无法确切的得知析构函数何时会被调用

              2,析构函数会延长对象的存活时间

              3,不要在析构函数中编写阻塞方法或耗时的方法,析构函数应该是迅速释放完资源并结束的

              4,如果程序运行期间一直没有进行垃圾回收,那么程序退出时会执行一次垃圾回收,并调用析构函数



  二,实现IDisposable接口

                

Finalizer的执行时间是不确定的,有时候,我们期望客户端对象使用完毕后立即释放资源,此时可以实现Idispose接口。


试用了下这个接口在dispose的时候都会发生啥,感觉还是雷同C++,写个栗子自己观察下析构的时候会发生啥吧。


使用示例:


<span style="font-family:Microsoft YaHei;"> static void Main(string[] args)
        {
            #region 构造器使用
            //Cup cup = new Cup() { 

            //    CupName="lhc的小杯子~~~~"
            //}; 
            #endregion


            #region dispose的使用
                BigCup bigCup = new BigCup()
                    {

                        CupName = "lhc的小杯子"
                    };

                //try
                //{
                //    bigCup.CupName = "此处模拟对象的使用过程";
                //}
                //finally
                //{

                //    IDisposable dis = bigCup as IDisposable;
                //    if (dis != null)
                //    {
                //        dis.Dispose();
                //    }
                //}

                using (bigCup as IDisposable)
                {
                    bigCup.CupName = "此处模拟对象的使用过程";
                }


            #endregion


        }
    }


    public class BigCup : IDisposable
    {
        public string CupName { get; set; }

        void IDisposable.Dispose()
        {

            Console.WriteLine("销毁了~~~~");
        }

    }

</span>



三,结合析构函数和Dispose()

        

       析构函数的主要问题在于:它不是立即被调用,而是在以后某个不确定的时间,执行垃圾回收时被调用。Dispose()方法也有自己的问题,就是客户端不一定会调用它。因此,最好的方法就是将这两者结合起来:

如果客户端调用了Dispose()方法,那么就不要让CLR去执行析构函数;

如果客户端没有调用,此时再进行析构。


       结合使用Demo:

      

<span style="font-family:Microsoft YaHei;">  public class TestFatherFinalizerAndDispose :IDisposable{

        private bool _dispose = false;

        ~TestFatherFinalizerAndDispose() {
            Console.WriteLine("调用析构函数~~~~");
        }

        public void IDisposable.Dispose() {

            if (!_dispose)
            {
                _dispose = true;
                CleanUp();
                GC.SuppressFinalize(this);//指示垃圾回收期,无视该对象的析构函数。
            }

        }

        //子类可重写该释放资源方法
        public virtual void CleanUp() { 
        
            //此处放置清理资源代码
            Console.WriteLine("垃圾清理完毕~");
        }
    }
    public class TestSonFinalizerAndDispose : TestFatherFinalizerAndDispose {

        public override void CleanUp()
        {
            try
            {
                Console.WriteLine("此处填写释放子类型资源的方法");
            }
            finally {
                base.CleanUp();  //调用父类的方法释放父类的资源
            }
            
        }
    
    }

</span>

     

       完美解决~~~继续准备运筹学考试,话说复习好无聊的,中间写个代码解解闷儿~~








                         

目录
相关文章
|
容器
.NET Core-作用域与对象释放行为详解
.NET Core-作用域与对象释放行为详解
|
1月前
|
数据库连接 开发者
.NET 内存管理两种有效的资源释放方式
【10月更文挑战第15天】在.NET中,有两种有效的资源释放方式:一是使用`using`语句,适用于实现`IDisposable`接口的对象,如文件流、数据库连接等,能确保资源及时释放,避免泄漏;二是手动调用`Dispose`方法并处理异常,提供更灵活的资源管理方式,适用于复杂场景。这两种方式都能有效管理资源,提高应用性能和稳定性。
|
1月前
|
算法 Java 数据库连接
.NET 内存管理两种有效的资源释放方式
【10月更文挑战第14天】在 .NET 中,`IDisposable` 接口提供了一种标准机制来释放非托管资源,如文件句柄、数据库连接等。此类资源需手动释放以避免泄漏。实现 `IDisposable` 的类可通过 `Dispose` 方法释放资源。使用 `using` 语句可确保资源自动释放。此外,.NET 的垃圾回收器会自动回收托管对象所占内存,提高程序效率。示例代码展示了如何使用 `MyFileHandler` 类处理文件操作并释放 `FileStream` 资源。
|
3月前
|
开发框架 前端开发 .NET
究竟是什么让.NET 开发者社区拥有如此强大的力量?资源、分享还是成长的秘密?
【8月更文挑战第28天】.NET开发者社区为成员提供了丰富的资源、积极的分享氛围和广阔的成长空间,是一个充满活力的知识宝库。在这里,从前沿的开源项目到深入的技术解析应有尽有,无论你是新手还是专家,都能找到适合自己的学习与交流机会,共同推动.NET技术的发展。
41 5
|
5月前
|
开发框架 .NET API
ASP.NET Core Web中使用AutoMapper进行对象映射
ASP.NET Core Web中使用AutoMapper进行对象映射
|
5月前
|
存储 分布式计算 大数据
MaxCompute操作报错合集之自定义udf的函数,引用了import net.sourceforge.pinyin4j.PinyinHelper;但是上传资源后,出现报错,是什么原因
MaxCompute是阿里云提供的大规模离线数据处理服务,用于大数据分析、挖掘和报表生成等场景。在使用MaxCompute进行数据处理时,可能会遇到各种操作报错。以下是一些常见的MaxCompute操作报错及其可能的原因与解决措施的合集。
108 0
|
6月前
|
C#
.NET开发中合理使用对象映射库,简化和提高工作效率
.NET开发中合理使用对象映射库,简化和提高工作效率
194 0
|
JSON 数据格式
.NET Core - 配置绑定:使用强类型对象承载配置数据
.NET Core - 配置绑定:使用强类型对象承载配置数据
|
容器
.NET Core作用域与对象释放行为详解
上节,我们提到,容器中有3种不同生命周期,分别是Singleton、Scoped和Transient。那么,你知道这3种类型的对象的释放时机和坑吗?
|
SQL 存储 缓存
SQl Server——ADO.NET五大对象
在某些编程中总是会需要用到数据库,那如何让应用程序和数据库之间建立联系呢?ADO.NET就提供了应用程序连接数据库的桥梁