1. 程式人生 > >C#定時清理記憶體,net網頁端可以嘗試使用

C#定時清理記憶體,net網頁端可以嘗試使用

-- in class definition

——在類定義中

[DllImport("KERNEL32.DLL", EntryPoint = "SetProcessWorkingSetSize", SetLastError = true, CallingConvention = CallingConvention.StdCall)]

internal static extern bool SetProcessWorkingSetSize(IntPtr pProcess, int dwMinimumWorkingSetSize, int dwMaximumWorkingSetSize);

[DllImport("KERNEL32.DLL", EntryPoint = "GetCurrentProcess", SetLastError = true, CallingConvention = CallingConvention.StdCall)]

internal static extern IntPtr GetCurrentProcess();

-- code to call when you want to reduce the memory

--要減少記憶體時呼叫的程式碼

IntPtr pHandle = GetCurrentProcess();

SetProcessWorkingSetSize(pHandle, -1, -1);

 

使用SetProcessWorkingSetSize函式並不能提高什麼效能,也不會真的節省記憶體,反倒往往會造成一些記憶體錯誤,造成應用程式或者系統不穩定,微軟自己也建議在建立程序,執行緒,核心池,就必須小心的使用該函式。

因為他只是暫時的將應用程式佔用的記憶體移至虛擬記憶體,一旦,應用程式被啟用或者有操作請求時,這些記憶體又會被重新佔用。如果你強制使用該方法來 設定程式佔用的記憶體,那麼可能在一定程度上反而會降低系統性能,因為系統需要頻繁的進行記憶體和硬碟間的頁面交換。

當我們的應用程式剛剛載入完成時,可以使用該操作一次,來將載入過程不需要的程式碼放到虛擬記憶體,這樣,程式載入完畢後,保持較大的可用記憶體。

這個東西一般就是整理記憶體的軟體用來騙人的,或者是對於記憶體佔用有強迫症的使用者,拿這個安慰他們。

記憶體佔用量的數值有很多種,你看到工作管理員的那個privateworkingset,有些記憶體佔用在這裡看不出來,比如開執行緒佔用的棧空間。實際上是要看virtualsize,如果32位程式超過了2GB,64位程式超過8TB,就會溢位。關於系統在資源方面的限制,做sysinternals的MarkRussinovich寫過可以參考。.net本身在分配記憶體的時候也有些限制,比如就算是在64位下,byte[]最大也只能是2GB。也有些溢位的錯誤並不是真正的溢位,比如GDI+的有些錯誤也會被誤報成溢位。定位記憶體洩漏有dotMemory/ANTSMemoryProfiler之類的工具可以用。它們就是監視一段時間的記憶體分配,在完全GC回收後,看還有哪些物件留下來,輔助你分析。

 

在應用程式中,往往為了釋放記憶體等,使用一些函式,其實,對於記憶體操作函式要謹慎使用,比如大家常常想到的 SetProcessWorkingSetSize,其實對於windows來說,系統會自動在程式閒置時(如程式被最小化)釋放記憶體的,自己用記憶體釋放 時,往往會造成一些莫名的記憶體錯誤,造成自己的應用程式及系統不穩定。