2012-12-05 46 views
4

這一個拋出OutOfMemoryException爲什麼要創建一個新的數組拋出OutOfMemoryException?

目標框架.NET 3.5,在64位Windows 2008 R2標準運行。

using System; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      byte[] test = new byte[Int32.MaxValue]; 
     } 
    } 
} 

根據文檔,數組長度必須只是一個正的32位整數,但顯然這並不是唯一需要注意的限制。

爲什麼在這種情況下內存不足?

+5

嗯,你知道,這マy內存不足 – sehe

+0

其他數據結構(如List )會動態分配內存,雖然這可能會有一些性能上的缺點,但可以避免聲明時內存不足。是否有理由聲明如此龐大的陣列? (我應該說'動態調整大小'而不是分配) – Charleh

+0

@sehe - 內存可用,但事實證明硬編碼[2GB限制對象大小](http://stackoverflow.com/a/13728766/426379) 。 – Saul

回答

8

這是2千兆字節的RAM。 32位int的最大值是2147483647,轉換爲兆字節是2048或2千兆字節。機器可能實際上已經耗盡內存。參見:Maximum Memory a .NET process can allocate

+1

幾乎但不完全;該問題歸結爲[受管理的.NET應用程序內任何**對象**的2GB限制](http://stackoverflow.com/a/13728766/426379)。 – Saul

1

在標準的32位系統上,由於RAM的大小,這是不可能的。你會溢出內存。在64位系統上,這是可能的,因爲您有更多的地址空間,但仍不推薦使用,因爲您希望支持32位和64位系統與任何標準應用程序。

+0

您仍然可以使用此代碼在64位計算機上溢出RAM。 –

+0

它仍然絕對有可能溢出!我只是解決了這個事實,即64位系統有更大的地址空間來包含這樣的請求。這仍然是不應該做的事情。 –

+0

@TheGreatCO一個32位系統*將*錯誤時,這樣做,64位系統*可能*錯誤時,這樣做。 – Servy

1

問題可能不是你沒有內存「可用」,但你已經分割內存太多,當你嘗試創建數組,並且它必須調整大小,沒有可用的單個塊內存可以容納它。

6

除了明顯的「內存不足」語義之外,還有一些稍微更棘手的堆碎片問題:可能有超過2Gb或RAM的可用空間,但它可能不是連續的

這被稱爲碎片。有一個dotNET堆分析器,可以告訴你什麼時候是這種情況。

+2

[Eric Lippert這樣說](http://blogs.msdn.com/b/ericlippert/archive/2009/06/08/out-of-memory-does-not-refer-to-physical-memory。 aspx)*相反,會發生「內存不足」錯誤,因爲進程無法在其虛擬地址空間中找到足夠多的連續未使用頁面來執行請求的映射。* –

1

Int32.MaxValue = 2 147 483 647個字節= 2048兆

參見this link

在「存儲器和地址空間限制」看到「用戶模式虛擬地址空間的每個32位過程」和「每個64位進程的用戶模式虛擬地址空間」。所以它似乎不是操作系統限制。

請參閱this link

相關問題