2013-08-04 57 views
0

編譯我有一個正在運行的內存只有當我與以下異常內存溢出異常時,應用在86

8/4/2013 11:36:52 AM: Main application context(1) CriticalError: Exception in Application context Run: Main application context : Parameter is not valid. at System.Drawing.Image.get_Width() 
    at System.Drawing.Image.get_Size() 
    at DevExpress.XtraBars.BarItem.IsSameSize(Image old, Image newImage) 
    at DevExpress.XtraBars.BarItem.set_Glyph(Image value) 
    at NordicIT.Mark5.Module.DM.Editor.frmEditorRibbon..ctor() 
    at NordicIT.Mark5.Module.DM.Editor.frmEditorRibbon..ctor(IEditFormForBOOptions editFormForBOOptions) 
    at NordicIT.Mark5.Module.DM.Actions.TDMActions.<>c__DisplayClass19.<_DocumentTransmitProcess>b__17() 
    at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) 

的內存消耗在Windows上運行它的x86 7模式下的.NET應用程序大約是400 mb,GDI對象在1500左右消耗(我已經增加了註冊表中的這些限制,所以不應該有任何問題需要大約10000)。

當我在x86中運行Windows Server 2008 R2中的相同應用程序時,我沒有任何問題(它應該與Windows 7具有相同的內核),在x86中的Windows XP中也沒有問題。

即使我的內存高達2 GB,我從來沒有在x64模式下出現異常。

請幫我理解我在達到的內存方面的限制。

+4

回溯沒有說任何關於內存問題 - 它說「參數無效」。 –

+0

以及您處理圖像時,在WPF中使用大或高分辨率圖像時,這會非常複雜。我想這背後的圖像是一個相當大的決議? WPF總是有問題 – Venson

+0

它似乎是'ArgumentException' –

回答

7

GDI +異常相當差,這是由於它早在.NET出現之前就開發出來的,並且只有一些錯誤代碼。在這樣的情況下,內存實際上很可能是問題所在。 「參數無效」是GDI +在爲什麼無法加載圖像的原因。其中可能是因爲圖像文件包含垃圾,反過來會讓它嘗試分配太多的內存。在很多情況下選擇不當。

32位進程擁有2千兆字節的虛擬內存,無論您的計算機具有多少內存。地址空間需要由代碼和數據共享。它的塊將被CLR,抖動,框架程序集,程序集,程序的jitted代碼以及.NET程序使用的大約10個不同的堆佔用,包括GC堆。這些塊的分配傾向於通過地址空間分散。當你分配內存的時候,你會從這些已經存在的塊之間的可用空洞中獲取另一塊。

位圖的一個大問題是它們可能相當於。他們需要適應一個可用的洞。隨着程序分配和釋放內存,這些漏洞會逐漸變小。一個稱爲「地址空間碎片」的問題。當你的程序第一次啓動時,你通常可以找到〜650兆字節的漏洞。但是當你的程序運行了一段時間後,這種情況迅速下降。長期運行的程序的危險區域約爲90兆字節。

當沒有可用的空洞足以容納位圖時,您的程序會發生此例外炸彈。這會在您的程序消耗完所有可用虛擬內存之前發生。你可以做很多小的分配,但不是一個大的分配。

這個問題沒有簡單的解決方法。除了一個。將EXE項目的目標平臺設置更改爲AnyCPU,關閉VS2012及更高版本的「首選32位」。在64位操作系統上,程序的虛擬機地址空間較大,可能會有太字節。你根本無法用盡足夠的漏洞。如果您遇到32位進程,一個困難的解決方法是使用另一個進程來加載位圖。這爲您帶來了另外2千兆字節的乾淨地址空間。不經常實用。

您可以使用SysInternals的VMMap實用程序來深入瞭解程序的VM使用情況。你可能找到一個加載在一個非常尷尬的地址的DLL,將一個大洞切割成兩個小塊。但是不要期待你的希望,你往往會首先完全淹沒數據。