[ASP.Net] 如何調整w3wp.exe所能使用之記憶體大小
※此問題僅存在x86系統之中,若使用x64系統作為Server不存在此類問題
前言
最近在使用擴充Gridview匯出Excel檔案時,
因為客戶需要一次性的匯出大量的資料 (約13000筆,匯出之Excel檔案大小約為13mb),
當連續多次執行匯出之後,可以在工作管理員中發現,
w3wp.exe所使用的記憶體量大的驚人,
而且當記憶體消耗量達到約1GB出頭的時候,
又再次執行匯出Excel,就很容易會產生OutofMemory Exception。
這是因為在x86系統中,Process的記憶體限制為2GB,
而在Asp.Net預設所能使用的記憶體限制為最大記憶體的60%,
因此當w3wp.exe所消耗的記憶體達到約1GB以上的時候,
就很容易會發生OutOfMemory Exception,
為了解決此問題,我們可以調整w3wp.exe所能使用的記憶體大小,
來降低此問題發生的機率。
實際演練
為了解決記憶體不夠用的問題,
我們主要可以針對兩個部分著手,
調整x86系統中每個process的記憶體限制以及Asp.Net預設所能使用的最大記憶體,
1. 調整x86系統中每個process的記憶體限制
在KB283037寫道:
一般而言,在 Windows 2000 或 Windows Server 2003 下執行程序時,
可以存取高達 2 GB 的記憶體位址空間 (假設沒有使用 /3GB 參數),
其中有些是實體記憶體,有些是虛擬記憶體。
執行的程式愈多 (也因而有更多處理程序),交付的記憶體就愈多,
最多可達 2 GB 的整個位址空間。
因此,我們可以藉由在Boot.ini使用 /3GB 參數,
來增加我們Process所能使用的記憶體大小至3GB,
首先我們可以找到Boot.ini的位址,預設是在C:\boot.ini且是隱藏的,
我們可以C:\透過"工具=>資料夾選項=>檢視"取消勾選"隱藏保護的作業系統檔案"來找到它。
再來我們可以發現boot.ini已經出現在我們的C:\中
我們可以替boot.ini的開機參數加上/3gb,來調整Process所能使用的最大記憶體至3GB
2.調整Asp.Net預設所能使用的最大記憶體
要調整此選項,我們必須開啟Asp.Net的machine.config,
系統預設的安裝位置是在 \WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG 中,
我們可以在processModel區段修改memoryLimit的預設值,調整為較大的百分比
修改完畢後儲存檔案,再重新啟動IIS即可
結語
除了以上兩種方法之外,
還可以設定IIS固定週期或範圍執行記憶體回收,可參考保哥的文章,
如果程式都在同一個app pool,可考慮使用Web Garden的方式,
但需要注意不支持HttpSessionState / HttpApplicationState,
或是將各個需要執行複雜運算的程式分散在不同的app pool等等方法,
更甚者是乾脆將系統一口氣升級至x64一勞永逸,
可以依照自己的需求做調整。
但這些東西畢竟也只是利用硬體的效能來緩衝問題的發生
最好的方法還是可以徹底的讓自己的程序可以在最適當的時間點釋放資源,
但這次的問題還沒找到解決的方法,如果有不正確的地方還請大家多多指教。