近期,使用c#+wpf開發的軟件准備正式投入使用了,使用前進行了大量的測試,測試后發現了一些問題,其中最讓人頭疼的就是軟件的性能問題(穩定性)。
這里的穩定性具體表現在機器的cpu占有率和內存使用情況:
1,CPU占用率節節攀升。
2,可用內存越來越少,最后爆OutOfMemoryException。
這兩點足以影響軟件的應用,一日不除,終日不得安寧!
發現問題后,多方搜尋資料,最終問題解決,這里做一些記錄,一來分享給各路開發者,二來記錄以備自己查看。
導致cpu占用率高:
1.是否有textbox的不斷循環中取值,賦值以及ScrollToend,解決方法:將TextBox控件換成ListBox,這樣是一行一行插入
2.搜索代碼中是否有while死循環。解決方法:優化代碼,刪掉死循環,while循環中可以加入
system.application.doevent();
thread.sleep(100);
我本人的項目中就是因為存在大量對textBox的操作,而導致的,我將TextBox控件換成ListBox后CPU占用率明顯下降。
導致可用內存越來越少的原因:
1.界面上很多動畫切換效果,如:gif動畫的幀切換,解決方法gif動畫暫用大量內存,需要及時釋放,盡量少用gif
2.界面上顯示很多圖片,圖片資源未回收,解決方法:釋放圖片資源
一:將Image類轉換成Bitmap類
System.Drawing.Image img = System.Drawing.Image.FromFile(filepath);
System.Drawing.Image bmp = new System.Drawing.Bitmap(img);
img.Dispose();
然后使用 bmp作為PictureBox的圖片源
二:從流中讀取
FileStream fileStream = new FileStream("文件名", FileMode.Open, FileAccess.Read);
pictureBox1.Image = Image.FromStream(fileStream);
fileStream.Close();
fileStream.Dispose();
3.非托管資源及其內存回收,對可能多次調用的類,應該嚴格按照“清理模式”格式書寫,保證類資源被及時釋放:
標准的清理模式(~dispose)寫法:
MyClass:IDisposable { private bool disposed = false; ~MyClass() { Dispose(false); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } private void Dispose(bool disposing) { if(disposed == false) { if(disposing == true) { // 釋托管代碼 ...... } // 釋非代碼 ...... } disposed = true; } }
4.確保萬無一失,使用using(){}來引用類,使用方法:
using(classA a =new classA()){
//用完后就釋放
}
只有繼承:IDisposable的類才能用using
5.網上給出了一個強制回收內存的方法,貌似看起來內存占用是減少了,一調用內存就降下來。先別高興太早,這其實是偽釋放,只為暫時解決內存大量泄露導致系統崩潰而急需解決的情況。
具體原因:http://blog.sina.com.cn/s/blog_49f8960e0100081x.html,關鍵字:將物理內存轉到虛擬內存,涉及磁盤讀寫。
ps:為了好看一點,我們可以加進去!
具體代碼:
[DllImport("kernel32.dll", EntryPoint = "SetProcessWorkingSetSize")] public static extern int SetProcessWorkingSetSize(IntPtr process, int minSize, int maxSize); /// <summary> /// 釋放內存 /// </summary> public static void ClearMemory() { GC.Collect(); GC.WaitForPendingFinalizers(); if (Environment.OSVersion.Platform == PlatformID.Win32NT) { SetProcessWorkingSetSize(System.Diagnostics.Process.GetCurrentProcess().Handle, -1, -1); } }
6.最后的殺手鐧,查看軟件中是否調用過什么開源插件,升級插件到穩定版本。
本人項目中就遇到這個問題,本人項目中使用了cefsharp插件,期初使用的是低版本,這次索性升級到最新版本,然后將.net框架也升級了(其中也遇到了一些問題,NuGet資源下載慢,.net升級后與原來的部分庫文件不匹配等,打怪升級各個擊破吧!),然后就奇跡的解決了問題,所以最后結論就是需要不斷的嘗試和改進,尋找一切可能的突破口來解決問題。
-------------------------------分隔線-----------------------
寫在最后:對於c#程序的性能優化工作,我們可以多實用工具,工欲善其事必先利其器,如:
1.vs自帶的性能分析工具:

分析->診斷,按照指導操作。
2.ANTS Performance Profiler和ANTS Memory Profiler,分別用來做性能分析和內存占用分析,講具體操作方法自行百度,能夠准確找到性能瓶頸所在。
3.DotTrace,和上面的工具類似。
4.可以安裝.net reflection來查看dll具體方法(可能會導致vs無法調試)
