2012-12-05 104 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

相关问题