• Effective C# Item16:尽量减少内存垃圾


        虽然.NET提供了垃圾回收机制,可以对托管的资源进行管理,但是创建对象和销毁对象本身,也是要花费时间的,特别是对于引用类型来说,频繁的创建和销毁引用类型的对象,对性能来说,是非常不好的。

        我们可以采取一些措施,来改善这种情况。

        首先,来看下面的代码。

    代码
    1 protected override void OnPaint( PaintEventArgs e )
    2 {
    3 // Bad. Created the same font every paint event.
    4   using ( Font MyFont = new Font( "Arial", 10.0f ))
    5 {
    6 e.Graphics.DrawString( DateTime.Now.ToString(),
    7 MyFont, Brushes.Black, new PointF( 0,0 ));
    8 }
    9 base.OnPaint( e );
    10 }
        如果OnPaint()方法被频繁调用,那么每次调用它时,程序都会创建一个包含相同设置的Font对象,而且在每次退出方法时,垃圾回收器都要删除它们,这样做事很没有效率的。

        我们可以将上面代码中的Font对象重构为类的成员变量,这样在调用OnPaint()方法时,就可以重用Font对象。

    代码
    1 private readonly Font _myFont =
    2 new Font( "Arial", 10.0f );
    3
    4 protected override void OnPaint( PaintEventArgs e )
    5 {
    6 e.Graphics.DrawString( DateTime.Now.ToString( ),
    7 _myFont, Brushes.Black, new PointF( 0,0 ));
    8 base.OnPaint( e );
    9 }
       当方法中的局部变量包含引用类型并且该方法会被频繁调用时,我们可以将引用类型的变量由局部变量提升为类型的成员变量,这种方式对于值类型来说,是没有必要的。

       然后,针对平时一些常用的引用类型,我们可以构建该类型的静态实例,这样可以保证类型只被实例化一次。另外,为了提升性能,可以对类型的实例实行延迟加载的策略,只在用到的时候,才会被加载。

       最后,当我们构造常量类型的固定值时,例如string,因为对string类型执行+=操作,就相当于重新创建一个string实例,这样在构造的过程中,会产生大量string中间实例,为了减少string实例的数目,我们可以使用stringbuilder来初始化。

       总结:垃圾收集器在管理应用程序所使用的内存方法非常有效,但是,记住创建和销毁对象仍然需要花费时间。我们应该避免创建过多的对象;不要创建不需要的对象。也要避免在局部方法内部创建多个引用类型的对象,相反,我们应该考虑将局部变量提升为类型的成员变量,或者为类型中的绝大多数常用类型创建一些静态实例,最后,对于具有常量性的类型,我们应该考虑为它们创建一个支持可变的生成类型。

  • 相关阅读:
    Nginx模块fastcgi_cache的几个注意点 转
    CGI与FastCGI 转
    APUE--UNIX环境编程
    与 在记事本中的内容表现方式 原创
    Linux 内核使用的 GNU C 扩展
    GCC内嵌汇编
    linux下64位汇编的系统调用系列
    查看源码Vim+Cscope
    GCC 编绎选项 转
    Linux系统启动流程 图解
  • 原文地址:https://www.cnblogs.com/wing011203/p/1646949.html
Copyright © 2020-2023  润新知