for循环的系统内存异常

时间:2013-12-12 06:11:44

标签: c#

我在下面有以下代码:

List<long> numbers = new List<long>();

for (long i = 1; i <= 300000000; i++)
{
    numbers.Add(i);
}

我想要做的是从1-3亿填充列表。但当它达到67108865时,它会在第4行抛出异常:Exception of type 'System.OutOfMemoryException' was thrown.

我尝试使用ulong,但仍然没有运气。

我认为long数据类型的最大范围是9,223,372,036,854,775,807,但为什么我在这里出错?

提前致谢!

修改 感谢所有的答案。它帮助我意识到我的设计并不好。我最终改变了我的代码设计。

4 个答案:

答案 0 :(得分:2)

嗯,这不是你的号码很大,但你的名单是...... 让我们计算它的大小:

300,000,000 * 64 bits (size of long) = 19,200,000,000 bits
19,200,000,000 /8 (size of byte) = 2,400,000,000
2,400,000,000 / 2^10 = 2,343,750 KB
2,343,750 / 2^10 = 2,288~ MB
2,288/ 2^10 = 2.235~ GB

您需要一个大约2.35 GB的列表。 当前CLR限制为2 GB(请参阅thisthis SO线程)

如果您需要一个大小为300,000,000的列表,请将其拆分为2个列表(或者使用或者使用将处理列表管理的包装对象)。

答案 1 :(得分:1)

首次注释System.OutOfMemoryException在变量达到限制时不会被抛出,
其次,它被抛出,因为没有足够的可用内存来继续执行程序 遗憾的是,你无法配置,.NET运行时做出有关堆大小和内存的所有决定 切换到64位计算机。

有关信息,在32位机器上,您可以使用Boot.ini中的/ 3GB启动开关选项来增加内存

编辑搜索时我在{{3>} 备注部分

下找到了
  

默认情况下,Array的最大大小为2千兆字节(GB)。在64位环境中,您可以通过在运行时环境中将gcAllowVeryLargeObjects配置元素的enabled属性设置为true来避免大小限制。但是,该阵列仍将限制为总共40亿个元素,并且在任何给定维度中最大索引为0X7FEFFFFF(对于字节数组和单字节结构数组,为0X7FFFFFC7)。

List<long>支持long[]。一旦无法分配后备阵列,您将失败,在重新分配期间,旧阵列和新阵列都必须有足够的总内存。

但是,如果你想要一个超过2个 31 元素的集合,你必须使用多个数组或List来编写自己的实现,并管理它们。

答案 2 :(得分:0)

你的数字不是太大;你的清单太长了。它正在使用所有可用内存。

300000000缩减为3000000,它(可能)可以正常工作。

答案 3 :(得分:0)

理想情况下,它应该包含您正在讲述的元素数量。

但是,根据当前CLR实现,每个对象的大小可以为2 GB。当您存储长值(大小为8个字节)时,在填充List时,它会尝试超过2GB的限制。这就是你得到System.OutOfMemoryException

的原因