当前位置 > 首页 > Asp.net

《Effective C#》读书笔记——条目16:避免创建非必要的对象<.NET资源管理>

2012-11-27 9:12:00来源:Asp.net

  我们知道:C#是一门虚拟机语言,C#编译器首先将C#代码编译成IL代码,运行程序时CLR(Common Language Runtime,公共语言运行时)通过调用JIT(just-in-time Compiler即时编译器)来将IL代动态即时编译成可执行的机器码。GC(Garbage Collector,垃圾收集器)自动为我们的应用程序进行内存管理的分配和释放,(具体参见:了解.NET 内存管理机制),以一种高效的方式来移除内存中的垃圾对象,不过不管有多高效,分配和销毁在堆上的对象总会花费掉时间。

  如果我们在一个方法中创建了过多的引用对象,会对应用程序的性能产生严重的影响。因此我们应该遵守下面的一些规则,可以尽量的降低GC的工作量。

 

阅读目录:

      1.将常用的局部变量提升为成员变量

      2.为常用的类型实例提供静态对象

      3.为不可变类型提供可变的创建对象

      小节

 

1.将常用的局部变量提升为成员变量

   所有的引用类型,包括那些局部变量,都会分配到堆上。在函数退出后,函数内的所有局部变量都会立即变成垃圾对象。所以我们可以得出结论:

若是某个引用类型(值类型无所谓)的局部变量用于被频繁调用的例程中,那么应该将其提升为成员变量。这既有助于减轻GC的负担,也可以提升程序运行的效率。

 在GUI编程中一个常见的错误就是:在窗体的Paint处理函数中创建GDI(Graphics Device Interface,图形设备接口)对象,如下:

1 protected override void OnPaint(PaintEventArgs e)
2 {
3 using (Font myFont = new Font("Arial", 10.0f))
4 {
5 e.Graphics.DrawString(DateTime.Now.ToString(), myFont, Brushes.Black, new Point(0, 0));
6 }
7 base.OnPaint(e);
8 }

 

OnPaint()将会被非常频繁的调用,每次调用都会创建一个Font对象,而包含的内容完全和上一次一样。所以GC需要每次都为你清扫这些垃圾,严重影响了应用程序的效率。其实我们完全可以将Font对象提升为成员变量,是每次窗体重绘时能够重用该Font对象:

1 private readonly Font myFont = new Font("Arial", 10.0f);
2
3 protected override void OnPaint(PaintEventArgs e)
4 {
5 e.Graphics.DrawString(DateTime.Now.ToString(), myFont, Brushes.Black, new Point(0, 0));
6
7 base.OnPaint(e);
8 }

 将常用的局部变量提升为成员变量之后,程序无需每次重绘时生成垃圾对象,减轻了GC的负担,也提升了程序的效率。不过这里有一个小小的限制:将实现了IDisposable接口的局部变量提升为成员变量,那么这个成员变量依附类本身也需要实现IDisposable接口。

 

2.为常用的类型实例提供静态对象

  静态成员变量可以让引用类型在类的各个实例中共享。我们可以通过提供了一个类,存放某个类型常用的实例的单例对象,这样可以避免创建重复的对象。.NET Framework 的类库中就有很多这样的做法:Brushes类包含了一系列的静态Brush对象,每个都包含了一种常用的颜色。它们的简要实现如下:

1 private static Brush blackBrush;
2 public static Brush Black
3 {
4 get

  • 模版引擎AderTemplate源代码分析笔记

    2007-7-13 19:15:00

    摘要: AderTemplate是一个小型的模板引擎。无论是拿来直接使用还是用来研究模板引擎实现方式,都是一个不错的选择。本文尝试对其源代码做一些分析。 阅读全文 kwklover 20

  • ASP.NET Web开发框架之六 数据库文档方法,工具和实践

    2012-9-29 9:25:00

    随着项目的进度推进,数据库的表越来越多,字段也频繁的变更。如何对这些变更作出文档说明,既要方便,又要有可维护性。比如,可以为所有的表创建WORD文档来说明,各个表的含义和字段的意义,但是如果数据库表

  • <推荐>35个优秀的电子商务网站界面

    2009-11-18 0:46:00

    阅读: 323 评论: 1 作者: 灵动生活 发表于 2009-11-17 22:35 原文链接 用户体验是在各个类型的网站中有着非常重要的位置,尤其对于电子商务网站更是如此。差的用户体

  • Profilers and ASP.NET

    2010-3-1 11:36:00

    There are a lot of different ways to troubleshoot ASP.NET issues.  I have gone over most of th

  • Android实例剖析笔记(七)

    2009-8-30 0:17:00

    摘要: 上一篇文章分析了Snake的界面Layout实现,本文将关注游戏主界面这个View是如何实现的,并提出了我的一些困惑之处,顺便也希望有朋友能指点一二。 -----------------

  • VS2008单步调试ASP.NET网站时无反应

    2011-11-7 17:05:00

    我以前是用的VS2005,现在用VS2008进行网站开发。我做的是一个简单的登录页面,当我把断点设置好后,按下F5就行调试。然后出现登录界面,我将用户名和密码输入后,点击登录按钮,结果直接出现用户名

  • Serializing and Deserializing Objects…to and from…XML

    2009-7-3 1:21:00

    Over on the Asp.Net forums I recently had the opportunity* to help a few lost souls by showing them

  • Hanselminutes Podcast 202 - A different way to do ASP.NET WebForms with WebFormsMVP

    2010-2-22 9:59:00

    My two-hundred-and-second podcast is up . I sit down (in my home, actually) with Tatham Oddie to

  • Web server controls in ASP.Net - part 1

    2010-9-23 7:41:00

    I am going to write a new series of blog posts regarding the most common web server controls we use

  • 了解.net MVC的实现原理

    2011-6-27 2:01:00

    通过Reflector反编译,我们对IIS分发请求至w3wp.exe进程之后交由HttpRuntime处理过程的分析了解HttpApplication,HttpModule,HttpHandler,