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

一,使用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>

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

时间: 2024-10-07 05:55:36

.net中对象占用资源的回收的相关文章

【Python】Python中对象管理与垃圾回收中两个很有意思的问题

再Python中是利用引用计数来实现对象管理和垃圾回收的,即其他对象引用该对象时候,其引用计数加1,反之减1,当引用计数为0时候,被垃圾收集器回收. Python解释器对对象以及计数器的管理分为以下两步: 1)其引用计数减1 2)判断引用计数是否为0,为0的话,销毁对象 因为使用引用计数,造成两个问题,GIL和循环引用 一.GIL(Global Interpreter Lock)全局解释器锁 试想一下在多线程中使用引用计数,比如线程a,b同时引用obj,那么obj的引用计数为2. 1)当a撤销对

JSP中的内置对象和Struts中的Web资源的详解

JSP中的内置对象有如下几种: request :继承于HttpServletRequest, HttpServletRequest继承ServletRequest, 获得的Request对象的方法:只能在Servlet中获取的doGet()和doPost()方法中获取 作用:封装用户请求信息 response   : 继承于HttpServletResponse,   HttpServletResponse继承ServletResponse 获得response对象的方法:只能在Servlet

Effective C++ 条款13/14 以对象管理资源 || 在资源管理类中小心拷贝行为

三.资源管理       资源就是一旦你使用了它,将来不用的时候必须归还系统.C++中最常用的资源就是动态内存分配.其实,资源还有 文件描述符.互斥器.图形界面中的字形.画刷.数据库连接.socket等. 1.        以对象管理资源       void f() {     investment *plv = createInvestment();     //这里存在很多不定因素,可能造成下面语句无法执行,这就存在资源泄露的可能.     delete plv; }      这里我们

c# -- 对象销毁和垃圾回收

有些对象需要显示地销毁代码来释放资源,比如打开的文件资源,锁,操作系统句柄和非托管对象.在.NET中,这就是所谓的对象销毁,它通过IDisposal接口来实现.不再使用的对象所占用的内存管理,必须在某个时候回收:这个被称为无用单元收集的功能由CLR执行. 对象销毁和垃圾回收的区别在于:对象销毁通常是明确的策动:而垃圾回收完全是自动地.换句话说,程序员负责释放文件句柄,锁,以及操作系统资源:而CLR负责释放内存. 本章将讨论对象销毁和垃圾回收,还描述了C#处理销毁的一个备选方案--Finalize

说说非托管资源的回收

释放未托管的资源有两种方法 1.析构函数 2.实现System.IDisposable接口 一.析构函数 构造函数可以指定必须在创建类的实例时进行的某些操作,在垃圾收集器删除对象时,也可以调用析构函数.析构函数初看起来似乎是放置释放未托管资源.执行一般清理操作的代码的最佳地方.但是,事情并不是如此简单.由于垃圾回收器的运行规则决定了,不能在析构函数中放置需要在某一时刻运行的代码,如果对象占用了宝贵而重要的资源,应尽可能快地释放这些资源,此时就不能等待垃圾收集器来释放了. 实例 C# 代码   复

.net非托管资源的回收

释放未托管的资源有两种方法 1.析构函数 2.实现System.IDisposable接口 一.析构函数 构造函数可以指定必须在创建类的实例时进行的某些操作,在垃圾收集器删除对象时,也可以调用析构函数.析构函数初看起来似乎是放置释放未托管资源.执行一般清理操作的代码的最佳地方.但是,事情并不是如此简单.由于垃圾回收器的运行规则决定了,不能在析构函数中放置需要在某一时刻运行的代码,如果对象占用了宝贵而重要的资源,应尽可能快地释放这些资源,此时就不能等待垃圾收集器来释放了. 实例 C# 代码   复

关于Activity调用Ondestroy()方法之后内存管理器为什么没有释放占用资源

最近在研究activity 执行了finish之后为什么还有很多资源没有释放的问题,关于这个原因的产生,最直接的想法就是activity里面还有很多资源没有手动释放,因为大家知道,activity只不过是一个高度抽象的UI组件,他仅仅只是一个控制界面的功能,包括分发touch时间还有一些列的作用,展示界面的工作是交给DecorView下的所有view以及viewGroup,所以我们可以认为activity持有了所有在他内部绑定的view的引用,但是这些view不仅仅只有activity的引用,还

简单聊聊java中如何判定一个对象可回收

背景 说到java的特性,其中一个最重要的特性便是java通过new在堆中分配给对象的内存,不需要程序员主动去释放,而是由java虚拟机自动的回收.这也是java和C++的主要区别之一:那么虚拟机是如何实现自动回收的呢?它的基本回收算法又是什么呢?  这篇随笔先不介绍这些~ ~,熟话说 饭要一口一口地吃,路要一步一步地走嘛,这篇随笔主要讲解的是回收的前提:如何判断一个对象可以回收. 对java中如何判断一个对象可以回收的一般性认识 在没有学习<深入理解java虚拟机>之前,对于java中判断一

关于hibernate中对象的三种状态分析

一,首先hibernate中对象的状态有三种:瞬态.游离态和持久态,三种状态转化的方法都是通过session来调用,瞬态到持久态的方法有save().saveOrUpdate().get().load():持久态到瞬态的方法有delete():游离态到持久态的方法有update().saveOrUpdate().lock():持久态到游离态的方法有:session.close().session.evict().session.clear(). 二,Hibernate的状态 hibernate的