Effective C#:儘量減少記憶體垃圾

iDotNetSpace發表於2010-01-14
   雖然.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來初始化。

 

   總結:垃圾收集器在管理應用程式所使用的記憶體方法非常有效,但是,記住建立和銷燬物件仍然需要花費時間。我們應該避免建立過多的物件;不要建立不需要的物件。也要避免在區域性方法內部建立多個引用型別的物件,相反,我們應該考慮將區域性變數提升為型別的成員變數,或者為型別中的絕大多數常用型別建立一些靜態例項,最後,對於具有常量性的型別,我們應該考慮為它們建立一個支援可變的生成型別。
    
作者:李勝攀
    
出處:http://wing011203.cnblogs.com/

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-625131/,如需轉載,請註明出處,否則將追究法律責任。

相關文章