Effective C#:儘量減少記憶體垃圾
雖然.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/
我們可以採取一些措施,來改善這種情況。
首先,來看下面的程式碼。
程式碼
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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Effective C#:儘量減少裝箱和拆箱C#
- curl 中減少記憶體分配操作記憶體
- C# 字串操作--減少垃圾回收壓力C#字串
- C# 垃圾回收釋放記憶體C#記憶體
- 通過減少記憶體使用改善.NET效能記憶體
- 使用String.intern減少記憶體使用記憶體
- C# 使用繫結控制程式碼來減少程式的記憶體耗用C#記憶體
- js儘量減少程式碼重複執行的次數JS
- 高效能web建站規則(儘量減少http請求)WebHTTP
- 字串池化,減少1/3記憶體佔用字串記憶體
- 谷歌Chrome瀏覽器引入省記憶體/省電模式:減少記憶體佔用谷歌Chrome瀏覽器記憶體模式
- win10系統下如何減少RAM記憶體使用Win10記憶體
- 微軟的HotSpot C2可減少15%堆記憶體分配微軟HotSpot記憶體
- python定時爬蟲啟用時如何減少記憶體?Python爬蟲記憶體
- 設計模式——使用模板方法模式儘量減少重複相似的程式碼段設計模式
- 減少.NET應用程式記憶體佔用的一則實踐記憶體
- .NET記憶體管理、垃圾回收記憶體
- java記憶體垃圾回收模型Java記憶體模型
- 減少Spring Boot的JVM記憶體佔用的Docker三種配置Spring BootJVM記憶體Docker
- python使用迭代生成器yield減少記憶體佔用的方法Python記憶體
- Node - 記憶體管理和垃圾回收記憶體
- Node記憶體限制和垃圾回收記憶體
- Java記憶體管理 -JVM 垃圾回收Java記憶體JVM
- JVM記憶體管理和垃圾回收JVM記憶體
- JavaScript 記憶體管理及垃圾回收JavaScript記憶體
- Node記憶體限制與垃圾回收記憶體
- 選擇合適Redis資料結構,減少80%的記憶體佔用Redis資料結構記憶體
- jvm:記憶體模型、記憶體分配及GC垃圾回收機制JVM記憶體模型GC
- 垃圾收集器與記憶體分配策略_記憶體分配策略記憶體
- golang 垃圾回收器如何標記記憶體?Golang記憶體
- C# 記憶體管理C#記憶體
- Effective Objective-C 2.0讀書筆記(一)-如何減少標頭檔案的引入Object筆記
- Java記憶體模型,垃圾回收機制,常用記憶體命令及工具Java記憶體模型
- Composer 2 真的可以減少或規避記憶體不夠的致命錯誤記憶體
- 揭秘!Vue3.5響應式重構如何讓記憶體佔用減少56%Vue記憶體
- PHP 垃圾回收與記憶體管理指引PHP記憶體
- JVM垃圾回收和記憶體分配策略JVM記憶體
- JVM的記憶體管理和垃圾回收JVM記憶體