C#中WPF內(nèi)存回收與釋放LierdaCracker的實現(xiàn)
使用wpf程序常常會出現(xiàn)一個問題,那就是內(nèi)存占用過高,使用wpf的程序功能越復(fù)雜往往用著用著內(nèi)存就本著90往上去了。
一方面wpf本身是一個ui框架,對圖像以及界面的渲染雖然提高了軟件的美觀性,但實際使用過程中調(diào)用和消耗了大量的內(nèi)存來進行協(xié)同處理;
另一方面這些調(diào)用的內(nèi)存的確在使用完成之后并沒有進行主動的釋放或者是只是自動釋放了一部分,即對于托管資源通過GC自動清理回收。對于非托管資源,通過代碼調(diào)用手動進行清除,再由GC回收。例如流,數(shù)據(jù)庫連接,網(wǎng)絡(luò)連接等,所以就需要我們主動定時的對內(nèi)存進行回收釋放的處理。
在這里非常推薦使用LierdaCracker
一.可以使用nuget管理安裝Lierda.WPFHelper包,在項目的App.xaml.cs中的Application_Startup方法里實例化并調(diào)用cracker方法直接使用
LierdaCracker cracker = new LierdaCracker(); cracker.Cracker();
二.自己實現(xiàn)LierdaCracker類
提到C#資源和內(nèi)存回收肯定少不了GC垃圾回收機制,托管堆上的內(nèi)存由GC全權(quán)負責, 值引用的在棧上的內(nèi)存會隨著??臻g的消亡而自動消失。
GC.Collect(); GC.WaitForPendingFinalizers();
此方法強制對所有代進行即時垃圾回收!
當應(yīng)用程序代碼中某個確定的點上使用的內(nèi)存量大量減少時,在這種情況下使用 GC.Collect 方法可能比較合適。而GC.WaitForPendingFinalizers則是提供收集完成前的等待。
另外一個非常重要的系統(tǒng)api在釋放內(nèi)存的時候也是非常重要的
SetProcessWorkingSetSize,使用這個函數(shù)來設(shè)置應(yīng)用程序最小和最大的運行空間,只會保留需要的內(nèi)存。當應(yīng)用程序被閑置或系統(tǒng)內(nèi)存太低時,操作系統(tǒng)會自動調(diào)用這個機制來設(shè)置應(yīng)用程序的內(nèi)存。應(yīng)用程序也可以使用 VirtualLock 來鎖住一定范圍的內(nèi)存不被系統(tǒng)釋放。
事實上,使用該函數(shù)并不能提高什么性能,也不會真的節(jié)省內(nèi)存。
因為他只是暫時的將應(yīng)用程序占用的內(nèi)存移至虛擬內(nèi)存,一旦,應(yīng)用程序被激活或者有操作請求時,這些內(nèi)存又會被重新占用。如果你強制使用該方法來 設(shè)置程序占用的內(nèi)存,那么可能在一定程度上反而會降低系統(tǒng)性能,因為系統(tǒng)需要頻繁的進行內(nèi)存和硬盤間的頁面交換。
BOOL SetProcessWorkingSetSize( HANDLE hProcess, SIZE_T dwMinimumWorkingSetSize, SIZE_T dwMaximumWorkingSetSize );
將 2個 SIZE_T 參數(shù)設(shè)置為 -1 ,即可以使進程使用的內(nèi)存交換到虛擬內(nèi)存,只保留一小部分代碼,它是windowsNT的api 所以使用的使用需要加上平臺條件。
if (Environment.OSVersion.Platform == PlatformID.Win32NT) SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, -1, -1);
綜合下來LierdaCracker類為
?public class LierdaCracker ?{ ?? ? [DllImport("kernel32.dll")] ? ? ?private static extern bool SetProcessWorkingSetSize(IntPtr proc, int min, int max); ?? ? private void FlushMemory() ? ? ?{ ? ? ? ? ? GC.Collect(); ? ? ? ? ? GC.WaitForPendingFinalizers(); ? ? ? ? ? if (Environment.OSVersion.Platform == PlatformID.Win32NT) ? ? ? ? ? ? ? SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, -1, -1); ? ? ? } ?? ? ?public void Cracker(int sleepSpan = 50) ? ? ? { ? ? ? ? ? ?_ = Task.Factory.StartNew(delegate ? ? ? ? ? ?{ ? ? ? ? ? ? ? ?while (true) ? ? ? ? ? ? ? ?{ ? ? ? ? ? ? ? ? ? ?try ? ? ? ? ? ? ? ? ? ?{ ? ? ? ? ? ? ? ? ? ? ? ?SetDate(); ? ? ? ? ? ? ? ? ? ? ? ?FlushMemory(); ? ? ? ? ? ? ? ? ? ? ? ?Thread.Sleep(TimeSpan.FromSeconds((double)sleepSpan)); ? ? ? ? ? ? ? ? ? ?} ? ? ? ? ? ? ? ? ? ?catch { } ? ? ? ? ? ? ? ?} ? ? ? ? ? ?}); ? ? ? ?} ?}
到此這篇關(guān)于C#中WPF內(nèi)存回收與釋放LierdaCracker的實現(xiàn)的文章就介紹到這了,更多相關(guān)C# WPF內(nèi)存回收與釋放 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#實現(xiàn)將javascript文件編譯成dll文件的方法
這篇文章主要介紹了C#實現(xiàn)將javascript文件編譯成dll文件的方法,涉及C#編譯生成dll動態(tài)鏈接庫文件的實現(xiàn)技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-11-11C# DataTable中查詢指定字段名稱的數(shù)據(jù)
這篇文章主要介紹了C# DataTable中查詢指定字段名稱的數(shù)據(jù),本文直接給出實例代碼,簡單易懂,需要的朋友可以參考下2015-06-06c#使用EPPlus將圖片流嵌入到Excel實現(xiàn)示例
這篇文章主要為大家介紹了c#使用EPPlus將圖片流嵌入到Excel實現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-12-12