【问题标题】:System memory exception on for loopfor循环的系统内存异常
【发布时间】:2013-12-12 06:11:43
【问题描述】:

我有以下代码:

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,但为什么我会出现错误?

提前致谢!

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

【问题讨论】:

  • 如果这是一个 32 位应用程序,您可能会达到可用地址空间的限制
  • 谢谢,但我仍然遇到错误,但现在在 134217729 上。我使用了 64 位设置。
  • 它可能是 List 容量尝试 LinkedList 代替
  • 杰拉德你在做什么,你一次需要这么多的对象在内存中?您可能需要使用不同的设计策略,例如将数据分成更小的块或使用数据库而不是将整个列表存储在内存中。
  • @ScottChamberlain 我正在解决 Project Euler 中的一个问题。我同意你的观点,因为我尝试使用 x64 位应用程序对列表进行分区,但我的计算机放弃了,因为我的 RAM 不足(仅限 4GB)。

标签: c#


【解决方案1】:

好吧,并不是您的人数过多,而是您的名单...
让我们计算一下它的大小:

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 个列表(就地或使用将处理列表管理的包装对象)。

【讨论】:

  • 我最终将其拆分为 3 个列表,但由于消耗了太多内存,我的机器最终没有响应。谢谢你的回答!
【解决方案2】:

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

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

EDIT 搜索时我在 Remarks 部分下的MSDN Documentation 中找到

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

List&lt;long&gt;long[] 支持。一旦无法分配后备数组,您就会失败,在重新分配期间,新旧数组都必须有足够的总内存。

但是,如果您想要一个包含超过 231 个元素的集合,则必须使用多个数组或List 编写自己的实现,并对其进行管理。

【讨论】:

  • 有什么方法可以配置我的机器为我的应用程序分配足够的内存来运行?
  • @Gerald 没有办法这样做,因为这是 CLR 限制,而不是“应用程序设置”
【解决方案3】:

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

300000000 减少到3000000,它(可能)会正常工作。

【讨论】:

  • 是的,3000000 可以正常工作,但我需要 300000000 作为要求的一部分。
【解决方案4】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-01
    相关资源
    最近更新 更多