.Net 內存溢出(System.OutOfMemoryException)的常見情況和處理方式總結


在什么情況下會出現OutOfMemonryException呢? 在我們試圖新建一個對象時,而垃圾收集器又找不到任何可用內存時被拋出,這種情況下我們是可以捕獲該異常的; 另一種情況是,CLR需要內存時,而卻系統卻不能提供,也會拋出該異常. 但此時,我們的應用程序是不能捕獲該錯誤的.

內存溢出(OutOfMemoryException)的調試分析

32位操作系統的尋址空間是4G,其中有2G被操作系統占用,也就是說留給用戶進程的內存只有2G(其中還要扣除程序加載時映像占用的部分空間,一般只有1.6G~1.8G左右可以使用)。 如果進程運行中需要申請內存,而操作系統無法為其分配內存空間,則會產生內存不足的異常,在.net中為System.OutOfMemoryException(The exception that is thrown when there is not enough memory tocontinue the execution of a program.)。 雖然最終的表現都為OutOfMemoryException,但其產生的原因可能是不一樣的,動手解決此問題之前需要先對進程當前內存的使用狀態進行分析,找出正確的原因,才能對症下葯。下面分享一下調試此類問題的一些心得。

更多內容請參考:http://blog.csdn.net/lazyleland/article/details/6704661

iis應用程序池 內存溢出錯誤 System.OutOfMemoryException

在ASP.NET Web服務器上,ASP.NET所能夠用到的內存,通常不會等同於所有的內存數量。在machine.config配置文件中,配置節<processModel>中有一個屬性“memoryLimit”,這個屬性的值是一個百分值,默認為“60”,即指定了ASP.NET進程(在任務管理器中大家就可以看到ASP.NET的進程,IIS5中為aspnet_wp,IIS6中為w3wp)能夠使用所有物理內存的60%。當ASP.NET使用的內存量超過這個限額時,IIS會開始自動回收(recycle)進程,即創建一個新的進程去負責應付Http請求,而將舊進程所占用的內存回收。

當我們有一台很大內存的服務器時,“memoryLimit”這個值是需要進行適當的調整的。比如我們准備了一台chemas-microsoft-com ffice marttags" />t="on">4G內存的服務器,那么t="on">4G×60%=t="on">2.4G。但是,對於Win32操作系統,一個進程所能占用的所有內存空間只有t="on">2G。當ASP.NET進程占用的內存開始達到t="on">2G時,由於它並沒有達到t="on">2.4G的“回收閾值”,所以IIS不會啟動recycle進程操作,但是由於Win32的限制,實際上已經不能給這個進程分配更多的內存了,於是,OutOfMemoryException就很可能會被拋出了。為了避免這樣的情況,我們就必須將“memoryLimit”適當調小,以讓IIS更早的進行進程回收。

微軟推薦的ASP.NET進程占用內存是不超過60%,並最好使計算出的實際值不超過t="on">800M。就是說,對於一台t="on">4G內存的服務器,最好將“memoryLimit”屬性設置成“20”。設置一個適當的回收閾值,讓IIS適時的進行進程回收,對於保證整個服務器的穩定運行,避免OutOfMemoryException是非常重要的。

在IIS6中,ASP.NET進程的回收閾值不再由配置節中的“memoryLimit”屬性決定,而是由IIS管理器中的應用程序池配置中的設置決定。

但是,即使正確設置了這些配置,也不能保證完全避免OutOfMemoryException的發生,原因可能是多樣而復雜的,比如內存回收操作可能耗時太多等等。開發人員要注意的,就是在代碼中時刻牢記不要無謂的使用和浪費內存。:)

如果你有一台大內存的服務器,同時對Win32操作系統中對於進程最高使用t="on">2G內存的限制很郁悶,可選的解決方法有兩個:

  1. 使用/3GB模式啟動計算機,方法參加文后的鏈接
  2. 使用Windows Server 2003 64bits Edition

避免內存溢出的幾點要素

如果要創建數組,請確保其大小正確。

確保有足夠的內存用於內部用途和新的托管對象。

如果您正在 .NET Compact Framework 上進行編程,當沒有足夠的內存可用於內部用途或新的托管對象時,公共語言運行庫會引發此異常。要避免此異常,應避免編寫占用 64KB 或更多內存的大方法。

過多的托管內存使用量通常由以下因素造成:

  1. 將大型數據集讀入內存中。
  2. 創建過多的緩存條目。
  3. 上載或下載大文件。
  4. 在分析文件時過多地使用正則表達式或字符串。
  5. 過多的視圖狀態。
  6. 會話狀態中有過多的數據或者會話過多。
  7. 當對 COM 對象調用一個方法,並且該方法返回包含安全數組(大小不固定的數組)的用戶定義類型時,可能引發此異常,並附帶一條額外的消息“存儲空間不足,無法完成此操作”。這是因為 .NET Framework 無法封送帶有安全數組類型的結構字段。

一種不當使用字節數組導致內存溢出的情況舉例

  1.  
    public partial class _Default : System.Web.UI.Page
  2.  
    {
  3.  
    protected void Page_Load(object sender, EventArgs e)
  4.  
    {
  5.  
    byte[] bytes = File.ReadAllBytes("D:\toClient.xls");//toClient.xls 大小為20M
  6.  
    Response.BinaryWrite(bytes);
  7.  
    }
  8.  
    }

上面的程序如果所輸出的文件特別大的話,有可能會直接報:System.OutOfMemoryException。正確的做法是把文件的字節流分段輸出,其實asp.net有現成的方法Response.WriteFile(filePath)就是這么做的。

如下是正確的寫法:

  1.  
    Response.ContentType = "application/octet-stream";
  2.  
    Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(downloadName, System.Text.Encoding.UTF8));
  3.  
    Response.WriteFile("D:\toClient.xls");
  4.  
    Response.Flush();
  5.  
    Response.End();

當asp.net出現內存溢出時,一種簡單的處理方法是馬上回收應用程序池。但是這樣並沒有徹底解決問題。

創建Image類型時出現內存溢出(System.OutOfMemoryException)

錯誤代碼: System.Drawing.Image myimg=System.Drawing.Image.FromFile(file.FullName);

當打開的文件不是圖像文件時會引發的異常:

MSDN:如果文件沒有有效的圖像格式,或者如果 GDI+ 不支持文件的像素格式,則此方法將引發 OutOfMemoryException 異常。

這樣的異常信息容易讓人誤解。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM