当前位置: 移动技术网 > IT编程>开发语言>.net > .net中对象占用资源的回收

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

2018年01月27日  | 移动技术网IT编程  | 我要评论
      一,使用Finalizer析构器   1,使用了Finalizer析构器的对象如何被回收?   在类中定

 

 

 

一,使用Finalizer析构器

 

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

 

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

 

2,使用示例

 

 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(小杯子已被打碎~~~~么么哒~~~~~);       
        }
    
    }


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

 

 

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

 

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

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

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

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


 

二,实现IDisposable接口

 

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

 

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

 

使用示例:

 

 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(销毁了~~~~);
        }

    }




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

 

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

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

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

 

结合使用Demo:

 

  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();  //调用父类的方法释放父类的资源
            }
            
        }
    
    }

 

 

 

 

 

 


 

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网