解決 ASP.NET 中 System.OutOfMemoryException 的問題

分享到噗浪!

這兩天去參加微軟技術菁英學院開的「ASP.NET 應用程式偵錯實戰專班」,雖然才短短兩天的時間,但學到的東西真是獲益良多阿,十分感謝 Terry 與 Louis 針對 Win32 Debugging 與 .NET Debugging 的精闢解析!日後如果有時間的話我也可以多分享一些關於 ASP.NET 偵錯相關技巧與心得,今天我想先分享一些關於 ASP.NET 中關於 System.OutOfMemoryException 的問題與解決方法。

我們之前也有台主機「偶而」會發生 System.OutOfMemoryException 的錯誤,原本想說可能是程式寫不好造成的,但怎麼查都查不太出來問題在哪裡,只要流量一大起來就有可能會導致這個例外狀況,完全是一籌莫展,這次去上課才得知也可能是因為 .NET 的記憶體回收行程 (GC) 所造成的問題。

之所以發生這個問題,是因為多處理器(或多核心)電腦上的 .NET CLR 的 Garbage Collection (GC) 機制預設是使用 Server Mode (伺服器模式) 在運作的,換句話說,就是「每一顆 CPU 都會有獨立的 GC 記憶體空間(堆積, Heap)」,所以如果你的 GC 記憶體空間 用掉了 500MB 且你有 4 顆 CPU 的話,就等於耗費了 2GB 的記憶體,進而發生 System.OutOfMemoryException 例外狀況!

要解決這個問題的方式就是將 GC 設定為 Workstation Mode (工作站模式),這樣就可以整台主機共用同一個 GC Heap,以節省記憶體的使用。要將預設的 GC 修改成 Workstation Mode 必須要修改 %WINDIR%\Microsoft.NET\Framework\v2.0.50727\Aspnet.config 檔案 ( 如果是 .NET 1.1 要修改 %WINDIR%\Microsoft.NET\Framework\v1.1.4322\Aspnet.config 檔案 ):

預設的 Aspnet.config 長這樣:

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <runtime>
        <legacyUnhandledExceptionPolicy enabled="false" />
        <legacyImpersonationPolicy enabled="true"/>
        <alwaysFlowImpersonationPolicy enabled="false"/>
        <SymbolReadingPolicy enabled="1" />
    </runtime>
</configuration>

需加上一行 <gcServer enabled="false"/> 如下:

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <runtime>
        <gcServer enabled="false" />
        <legacyUnhandledExceptionPolicy enabled="false" />
        <legacyImpersonationPolicy enabled="true"/>
        <alwaysFlowImpersonationPolicy enabled="false"/>
        <SymbolReadingPolicy enabled="1" />
    </runtime>
</configuration>

這樣就設定完成了!

不過像這種出現 Out of Memory 的例外狀況在 64 位元的作業系統中幾乎不會出現問題,所以如果你是用 64 位元的作業系統(如:Windows Server 2003 64bit ) 的話,是不太需要做這樣的調整的,但你的記憶體還是要夠多才行,否則過多的分頁狀況還是會降低你 ASP.NET 應用程式的執行效能!

除了這點之外,在正式(Production)環境中的 ASP.NET 應用程式一定要在 web.config 中關閉開發時期設定的 debug 與 trace,才不會對記憶體造成額外的負擔。因為 ASP.NET 應用程式在啟用 debug mode 的時候所有的 Symbol 檔(*.pdb)都會被載入到記憶體中,不但會消耗不少記憶體,也會降低執行效能。詳情請見微軟知識庫:Quick things to check when you experience high memory levels in ASP.NET

相關連結

 

  

此文章由 will 發表於 2008/5/7 下午 09:13:00

永久連結 | 評論 (5) | 此文章的RSSRSS comment feed |

分類: .Net | ASP.NET | IIS | 系統管理

標籤: , , , ,

評論

十月 15. 2009 09:41

digitalwow

您好.
也加上了<gcServer enabled="false"/> 但每一天還是會有這訊息..都只好重開了..看看疑難排解例外狀況:System.OutOfMemoryException 的介紹..
使用過多的 Managed 記憶體,通常是因為:

將大量資料集讀入記憶體中。
建立過多的快取項目。
上傳或下載大型檔案。
剖析檔案時,使用太多規則運算式 (Regular Expression) 或字串。檢視狀態過多。
工作階段狀態中有過多資料,或工作階段過多。

還是不知如何下手..不知道還有沒有法子....謝謝.

伺服器是2G.(iis6+sql 2005 express) 還是建議如何配置ram...

digitalwow 台灣

十月 15. 2009 14:10

Will 保哥

如果你已經設定了這些建議的項目還是不斷發生 System.OutOfMemoryException 的話,通常就是應用程式的問題了,這就要重新檢視程式的寫法才行,否則再多的 Ram 也不夠用。

Will 保哥 台灣

五月 11. 2010 11:53

well

能否請問您一個問題,就在剛剛我在國內某書局網站上註冊,結果當我填好一堆資料,按下"送出"時,卻出現"Server Application Unavailable"錯誤,進一步檢視網頁說明是[OutOfMemoryException: Exception of type System.OutOfMemoryException was thrown.],Microsoft .NET Framework Version:1.1.4322.2443; ASP.NET Version:1.1.4322.2407。之後某網站就連不上了。因為上面填了很多個人隱私資料(包含身分證字號等),雖然google chrome網址列有顯示安全連線(顏色變黃,鎖頭),還是覺得有點擔心。不知道當我按下"送出"時,我的個人資料,在這種情形下會如何處理??

well 台灣

五月 11. 2010 12:40

Benson

我也遇到這樣的問題
這就來處理一下
謝謝分享

Benson 台灣

五月 12. 2010 13:38

Will 保哥

well: 他網站死了,資料不一定會儲存,至於他們會怎麼處理就要看該網站怎麼處理了。

Will 保哥 台灣

新增評論


( 您輸入的Email不會顯示於網站上 )

  Country flag

biuquote
  • 評論
  • 線上預覽
Loading