OutOfMemoryException错误

时间:2011-01-29 12:38:14

标签: c#

我只是在我的Windows应用程序项目中写了两行

double[] results = new double[100000000];

double[] results1 = new double[100000000];

在第二行(results1)我得到了异常'System.OutOfMemoryException'被抛出。

我的系统配置是

RAM- 4 gb

操作系统 - Windows 7

处理器 - 两核2.93 Ghz的英特尔核心

如何解决此错误以及发生此错误的原因

好的,因为大部分答案都适用于通用列表

       List<int> results1 = new List<int>();
         List<int> results2 = new List<int>();



        for (int i = 0; i <= 100000000; i++)
        {
            results1.Add(i);
            results2.Add(i);
        }

我在这里也得到了同样的错误

7 个答案:

答案 0 :(得分:8)

创建数组时,内存分配器将尝试保留分配点所需的总内存量。在这种情况下,每个元素将为8个字节。在这种情况下,OOM非常简单,没有足够的内存来分配这样的大型数组。在标准的32位Windows配置中,对于用户代码和数据,每个进程最多只能有2GB的内存地址空间,但实际上由于内存碎片,它通常比这少得多。在碎片化的情况下,在处理大型数组时,OOM被更好地解释为“找不到足够大的连续内存部分”。

答案 1 :(得分:5)

你不应该分配那些不适合内存的大型数组。只需使用列表并根据需要添加元素:

var results = new List<double>();

来自documentation

的引用
int[] array = new int[5];
  

此数组包含来自的元素   array [0]到array [4]。新的运营商   用于创建数组和   将数组元素初始化为它们的   默认值。在这个例子中,所有   数组元素初始化为   零

所以你需要有足够的内存来保存这些默认值。

答案 2 :(得分:5)

这是一个800MB阵列,您尝试加载到win32进程空间(2GB)。它也需要连续,这使得它更难。简单 - 在LOH中找不到一个足够大的连续区块,以便将所有这些整合在一起。

三个选项:

  • 不要分配如此庞大的数组 - 真的需要吗?
  • 切换到锯齿状阵列;分配多个中型数组更容易;例如,double[][]有10000个内部数组,每个数组长度为10000 - 只需执行一些/%代码即可进入正确的块
  • 切换到x64(注意阵列仍然难以限制为2GB)

答案 3 :(得分:2)

我可能错了,但通常(意思是,至少在大多数语言中)分配数组时,这意味着您要求连续内存块。具有100,000,000个元素的单个双精度数组将需要100000000 * 8字节的内存(+可能的开销),大约800兆字节。即使你说的内存量(总计),也不一定意味着空闲内存是连续的,它可能被分割成不同大小的多个空闲区域,并且分配将失败。

答案 4 :(得分:2)

一个可能的原因是虚拟地址空间碎片:内存管理器可以找到第一个800MB连续的地址空间块。但它找不到第二个。

答案 5 :(得分:1)

据我所知,列表的工作原理如下:如果列表的长度超过2 ^ n,则分配另外2 ^ n个元素。因此,在列表的长度为67108864(= 2 ^ 26)时,它将分配另外2 ^ 26个元素。如果我正在运行您的代码,那也正是错误发生的地方。如果你使用长变量而不是int,你将得到长度为33554432的错误,正好是2 ^ 25。这也是有道理的。

所以你的第一个列表 - 在它变得超过2 ^ 26的那一刻 - 已经分配了一个2 ^ 27 * 4字节的内存空间,因为一个int需要4个字节,所以这是2 ^ 29个字节。在您尝试为第二个列表分配更多空间的那一刻,您的内存超过2 ^ 30字节,即1GB。

这就是为什么我认为存在一个基本内存RAM限制,它不仅仅是关于自由连续的地址空间,而且还有大约1 GB的RAM限制。我不确定这个限制到底在哪里。

在32位机器上有一些关于类似问题的帖子here - 我不知道你的win 7是32还是64位。 编辑:我现在以64位模式运行您的应用程序,问题就消失了。所以我可以再次参考上面的帖子。您应该将项目属性中的平台更改为64位。

只留下一个问题:为什么你想要这么大的名单?这实际上是内存消耗,有很多方法可以避免这样的分配。

希望有所帮助。

答案 6 :(得分:0)

错误的原因是数组太大,以至于在运行代码时会占用系统上的所有免费ram。达林所说的是对的。制作一个大的数组是没有意义的。迭代将需要永远,并且在大多数系统上都会占用太多内存。