程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> Effective C#原則16:垃圾最小化(1)

Effective C#原則16:垃圾最小化(1)

編輯:關於C語言
圾回收器對內存管理表現的非常出色,並且它以非常高效的方法移除不再 使用的對象。但不管你怎樣看它,申請和釋放一個基於堆內存的對象總比申請和 釋放一個不基於堆內存的對象要花上更多的處理器時間。你可以給出一些嚴重的 性能問題,例如應用程序在某個方法內分配過量的引用對象。

你不應該 讓垃圾回收器超負荷的工作,為了程序的效率,你可以使用一些簡單的技巧來減 少垃圾回收器的工作。所有的引用類型,即使是局部變量,都是在堆上分配的。 所有引用類型的局部變量在函數退出後馬上成為垃圾,一個最常見的“垃 圾”做法就是申請一個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;
 }
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved