zoukankan      html  css  js  c++  java
  • C#之垃圾回收

    垃圾回收时现代语言的标志之一。垃圾回收解放了手工管理对象释放的工作,提高了程序的健壮性,但是副作用就是程序代码可以对于创建对象变得随意。

    1、避免不必要的对象创建

         由于垃圾回收的代价较高,所以C#程序开发要遵循的一个基本原则就是避免不必要的对象创建。以下列举一些常见的情型。

    a)、避免循环创建对象

          如果对象并不会随每次循环改变而改变状态,那么在循环中反复创建对象将带来性能损耗。例如下面的例子:

                SqlBuildResults BuildUpdate(IEntityMap Map,IObjectValue date)
                {
                    SqlBuildResults results = new SqlBuildResults();
                    foreach(IORMap ormap in map.Maps)
                    {
                        UpdateBuilder builder = new UpdateBuilder();
                        SqlBuildResults result = builder.BuildUpdate(ormap,date);
                        if(result != null)
                            results.AddRange(result);
                    }
                    return results;
                }

           高效的做法是将builder对象提到循环外面创建。

    b)、在需要的逻辑分支中创建对象

          如果对象只在默写逻辑分支中才被用到,那么应该只在该逻辑分支中创建对象。例如:

            protected virtual object OnGetRelation(string childAttrName, IAssociaton association, object relation)
            {
                ObjectRelationEventArgs args1 = new ObjectRelationEventArgs(association, relation, relation);
                if (this.GetRelation != null)
                {
                    this.GetRelation(childAttrName, this.Anchor, args1);
                    relation = args1.NewRelation;
                }
                return relation;
            }

         正确的做法是:

            protected virtual object OnGetRelation(string childAttrName, IAssociaton association, object relation)
            {
                if (this.GetRelation != null)
                {
                    ObjectRelationEventArgs args1 = new ObjectRelationEventArgs(association, relation, relation);
                    this.GetRelation(childAttrName, this.Anchor, args1);
                    relation = args1.NewRelation;
                }
                return relation;
            }

    c)、使用常量避免创建对象

          如下例,程序中存在大量new decimal(0)的代码,这会导致小对象频繁创建及回收;

                if (convert1.FromDualQty.RateToBase == new decimal(0))
                {
                    comvert1.FromDualQty.RateToBase == UOMConvertRatio.GetRationBy(……);
                }
                if (convert1.ToQty.RateToBase == new decimal(0))
                {
                    comvert1.FromDualQty.RateToBase == UOMConvertRatio.GetRationBy(……);
                }

          正确的做法是使用Decimal.Zero常量。另外,我们也可以学习这个设计手法,应用到类似场景中。

    d)、使用StringBuilder做字符串连接

    2、不要使用空析构函数

          如果类中包含析构函数,则创建对象时会在Finalize队列中添加对象的引用,以保证当对象无法到达时,人人可以调用到Finalize方法。垃圾回收 器在运行期间,会启动一个低优先级的线程处理该队列。相比之下,没有析构函数的对象就没有没有这些小号。如果析构函数为空,这个消耗就毫无意义,只会导致 性能降低!因此,我们尽量不要使用空的析构函数。

          从实际情况来看,许多是曾经在析构函数中包含有处理代码,但后来因为种种原因被注释掉或者删除掉了,只留下一个空的析构函数。此时应该注意把析构函数本身注释掉或者删除掉。

    3、实现IDisposable接口

          垃圾回收事实上只支持托管内存的回收,对于其它的非托管的资源,例如:WindowsGDI句柄或数据库连接,在析构函数中是否资源有很大问题,原因是垃圾回收依赖于内存紧张情况,虽然数据库连接可能已濒临耗尽,但如果内存还很充足的话,垃圾回收是不会运行的。

          C#的IDisposable接口是一种显式释放资源的机制。通过提供using语句,还简化了使用方式(编译器自动生成try…finally块,并在 finally块中调用Dispose方法)。对于申请了非托管资源的对象,应为其实现IDisposable接口,并保证资源一旦超出using语句范 围,即得到及时的释放。这对于构造函数健壮且性能优良的程序非常有意义!

          为防止对象的Dispose方法不被调用的情况发生,一般还要提供析构函数,两者调用一个出来资源释放的公共方法。同时,Dispose方法应调用 System.GC.SuppressFinalize(this),告诉垃圾回收器无需在处理Finalize方法了。

    原文地址:http://www.cnblogs.com/lijun198504/archive/2010/01/19/1651729.html

  • 相关阅读:
    iOS8中用UIVisualEffectView实现高斯模糊视图(毛玻璃效果)
    IOS推荐学习网站
    Xcode因为证书问题经常报的那些错
    bug集合令
    html5的标签
    CSS小总结
    JS中的闭包
    前端之路宣告式
    linux安装mysql数据库
    yarn环境搭建
  • 原文地址:https://www.cnblogs.com/Gxiaopan/p/4201152.html
Copyright © 2011-2022 走看看