Effective C#原则16:垃圾最小化

垃圾回收器对内存管理表现的非常出色,并且它以非常高效的方法移除不再 使用的对象。但不管你怎样看它,申请和释放一个基于堆内存的对象总比申请和 释放一个不基于堆内存的对象要花上更多的处理器时间。你可以给出一些严重的 性能问题,例如应用程序在某个方法内分配过量的引用对象。

你不应该 让垃圾回收器超负荷的工作,为了程序的效率,你可以使用一些简单的技巧来减 少垃圾回收器的工作。所有的引用类型,即使是局部变量,都是在堆上分配的。 所有引用类型的局部变量在函数退出后马上成为垃圾,一个最常见的“垃 圾”做法就是申请一个Windows的画图句柄:

protected override void OnPaint( PaintEventArgs e )
{
 // Bad. Created the same font every paint event.
 using ( Font MyFont = new Font( "Arial", 10.0f ))
 {
   e.Graphics.DrawString( DateTime.Now.ToString(),
   MyFont, Brushes.Black, new PointF( 0,0 ));
 }
 base.OnPaint( e );
}

OnPaint()函数的调用很频繁的,每次调用它的时候, 都会生成另一个Font对象,而实际上它是完全一样的内容。垃圾回收器每次都须 要清理这些对象。这将是难以置信的低效。

取而代之的是,把Font对象 从局部变量提供为对象成员,在每次绘制窗口时重用同样的对象:

private readonly Font _myFont =
 new Font( "Arial", 10.0f );
protected override void OnPaint( PaintEventArgs e )
{
 e.Graphics.DrawString( DateTime.Now.ToString( ),
  _myFont, Brushes.Black, new PointF( 0,0 ));
 base.OnPaint( e );
}

这样你的程序在每 次paint事件发生时不会产生垃圾,垃圾回收器的工作减少了,你的程序运行会 稍微快一点点。当你把一个实现了IDisposable接口的局部变量提升为类型成员 时,例如字体,你的类同样也应该实现IDisposable接口。原则18会给你解释如 何正确的完成它。

当一个引用类型(值类型的就无所谓了)的局部变量在 常规的函数调用中使用的非常频繁时,你应该把它提升为对象的成员。那个字体 就是一个很好的例子。只有常用的局部变量频繁访问时才是很好的候选对象,不 是频繁调用的就不必了。你应该尽可能的避免重复的创建同样的对象,使用成员 变量而不是局部变量。

前面例子中使用的静态属性Brushes.Black,演示 了另一个避免重复创建相似对象的技术。使用静态成员变量来创建一些常用的引 用类型的实例。考虑前面那个例子里使用的黑色画刷,每次当你要用黑色画刷来 画一些东西时,你要在程序中创建和释放大量的黑色画刷。前面的一个解决方案 就是在每个期望黑色画刷的类中添加一个画刷成员,但这还不够。程序可能会创 建大量的窗口和控件,这同样会创建大量的黑色画刷。.Net框架的设计者预知了 这个问题,他们为你创建一个简单的黑色画刷以便你在任何地方都可以重复使用 。Brushes对象包含一定数量的静态Brush对象,每一个具有不同的常用的颜色。 在内部,Brushes使用了惰性算法来,即只有当你使用时才创建这些对象。一个 简单的实现方法:

private static Brush _blackBrush;
public static Brush Black
{
 get
 {
  if ( _blackBrush == null )
   _blackBrush = new SolidBrush( Color.Black );
   return _blackBrush;
 }
}

时间: 2025-01-30 06:28:05

Effective C#原则16:垃圾最小化的相关文章

Effecitve C#原则46:最小化与其它非托管代码的交互

在开发设计.Net时,MS所做的最聪明的修改之一就是他们意识到,如果没有 办法整合已经存在的代码到新的.Net环境中,那没没有人会接受这个新的平台. MS知道,如果没有办法来利用已经存在的代码,这将阻止大家接受它.与其它非 托管代码的交互是可以工作了,但这是可交互唯一可以拿来说一下的有利的地方 .对于所有的交互策略,当操作流程在本地代码和托管代码之间的边界上进行传 送时,都要求强制提供一些 编组的信号.同时,交互策略强迫开发人员必须手 动的申明所有调用参数(译注:这里是说你根本不知道参数的数据类

《Effective Java》笔记 使类和成员的可访问性最小化

类和接口 第13条 使类和成员的可访问性最小化 1.设计良好的模块会隐藏所有的实现细节,把它的API与实现清晰的隔离开来,模块之间只通过它们的API进行通信,一个模块不需要知道其他模块的内部工作情况:即信息隐藏或封装,是软件设计的基本原则之一. 2.Java提供了许多机制来协助信息隐藏.访问控制(access control)机制决定了类.接口和成员的可访问性(accessibility). 3.第一规则:尽可能地使每个类或者成员不被外界访问.或者说在保证功能的情况下,使用最小的访问级别. 4.

unix安全编程:最小化特权

安全的程序必须最小化特权,以降低 bug 转化为安全缺陷的可能性.本文讨论了如何通过最小化有特权的模块.授与的特权以及特权的有效时间来最小化特权.文章不仅讨论了一些传统的类 UNIX 特权机制,还讨论了较新的机制,如 FreeBSD 的 jail(),Linux 安全模块(Linux Security Modules,LSM)框架,以及 Security-Enhanced Linux(SELinux). 2003 年 3 月 3 日,Internet Security Systems 对 Sen

Delphi模拟最小化恢复关闭按纽

我们做多文档应用程序开发时,如果在主From中指定mainMenu时,在主菜单上右角上会自动出现最小化,恢复,关闭按纽,但主菜单放入Toolbar等中时,该三个按纽不会自动出现,因此需要编程实现. 实现原理: 按纽的实现,从Tbitbtn继承下来最理想,但需要过滤TbitBtn的焦点响应消息,使其不能获得焦点状态. 按纽的功能的实现是比较关键的,Delphi中提供了标准action对象(Twindowclose)来实现关闭当前激活的子窗体的功能. 当没有提供最小化及恢复功能的Action,因此有

Effective C#原则43:请勿滥用反射

创建二进制的组件时,同时也意味着你要使用迟后绑定和反射来查找你所须 要的具有特殊功能代码.反射是一个很有力的工具,而且它让你可以写出可动态 配置的软件.使用反射,一个应用程序可以通过添加新的组件来更新功能,而这 些组件是在软件最开始发布时没有的.这是有利的. 这一伸缩性也带来 了一些复杂的问题,而且复杂问题的增加又会增加出现其它问题的可能.当你使 用反射时,你是围绕着C#的安全类型.然而,成员调用的参数和返回值是以 System.Object类型存在的.你必须在运行时确保这些类型是正确的.简单的

Effective C#原则42:使用特性进行简单的反射

当你创建了一个与反射相关的系统时,你应该为你自己的类型,方法,以及 属性定义一些自己的特性,这样可以让它们更容易的被访问.自定义的特性标示 了你想让这些方法在运行时如何被使用.特性可以测试一些目标对象上的属性. 测试这些属性可以最小化因为反射时可能而产生的类型错误. 假设你须 要创建一个机制,用于在运行时的软件上添加一个菜单条目到一个命令句柄上.这个须要很简单:放一个程序集到目录里,然后程序可以自己发现关于它的一些 新菜单条目以及新的菜单命令.这是利用反射可以完成的最好的工作之一:你的 主程序须

Effective C#原则32:选择小而内聚的程序集

这一原则实际应该取这个名字:"应该创建大小合理而且包含少量公共 类型的程序集".但这太沉长了,所以就以我认为最常见的错误来命名: 开发人员总是把所有的东西,除了厨房里水沟以外(译注:夸张说法,kitchen sink可能是个口语词,没能查到是什么意思,所以就直译了.),都放到一个程 序集.这不利于重用其中的组件,也不利于系统中小部份的更新.很多以二进制 组件形式存在的小程序集可以让这些都变得简单. 然而这个标题对于程 序集的内聚来说也很醒目的.程序集的内聚性是指概念单元到单个组件的职责

WinForm实现最小化到系统托盘方法实例详解

  本文实例讲述了WinForm实现最小化到系统托盘方法.分享给大家供大家参考.具体分析如下: 有个叫NotifyIcon的控件 1.建个WinForm项目,其它操作略过. 2.拉个NotifyIcon控件,将属性Visable设置成False,在Text属性上随便填些文件. 3.实现Form的SizeChanged事件,代码如下: ? 1 2 3 4 5 if(this.WindowState == FormWindowState.Minimized) //判断是否最小化 { this.Sho

生产服务器环境最小化安装后Centos 6.5优化配置备忘

生产服务器环境最小化安装后 Centos 6.5优化配置备忘 本文 centos 6.5 优化 的项有18处,列表如下: 1.centos6.5最小化安装后启动网卡 2.ifconfig查询IP进行SSH链接 3.更新系统源并且升级系统 4.系统时间更新和设定定时任 5.修改ip地址.网关.主机名.DNS 6.关闭selinux,清空iptables 7.创建普通用户并进行sudo授权管理 8.修改SSH端口号和屏蔽root账号远程登陆 9.锁定关键文件系统(禁止非授权用户获得权限) 10.精简