【问题标题】:What causes "Exception of type 'System.OutOfMemoryException' was thrown."for this code? [closed]是什么原因导致“引发了‘System.OutOfMemoryException’类型的异常。”对于这段代码? [关闭]
【发布时间】:2013-01-06 15:20:38
【问题描述】:
class Node
{
    public Node next;
    public int data;

    public Node(int d)
    {
        this.data = d;
    }
}

class Program
{
    static void Main(string[] args)
    {
        Node n1 = new Node(10);
        Node n2 = null;

        Node root = n1;

        int count = 1;

        while (count < Int32.MaxValue -1)
        {
            n2 = new Node(count); //Exception
            n1.next = n2;

            n1 = n2;
            count++;

         }

}

当系统内存达到 3 of 16GB 时发生异常

【问题讨论】:

  • Int32.MaxValue 是一个很大的值 2^31-1 = 2 147 483 647,你需要将它与每个节点的内存相乘。
  • 您的系统内存已用完异常 - 都在错误消息中!
  • 如果你创建了 21 亿个东西,你可能想重新考虑如何存储它,也许你应该使用 SQL,但是我希望看到这些节点被写入一个 xml 文件:)跨度>
  • 您运行的是 32 位操作系统,并启用了 4GT 调整吗?这可以解释为什么当进程的虚拟内存达到 3GB 时会出现异常。

标签: c# .net memory linked-list


【解决方案1】:

Int32.MaxValue 是一个大数字,您正在创建节点的新实例乘以该数字。这很可能会超过您可用的内存量或操作系统允许进程拥有的内存量。

【讨论】:

  • 不,它不是一个很大的数字:) 但是,VM 为对象安排了更多的内存。
【解决方案2】:

正如其他评论者所说,Int32.MaxValue 是一个很大的数字(大约 24 亿),每个 Node 至少需要 8 个字节的标头 - 所有 .NET 对象都有这个 - 再加上四个用于 Node 引用,再加上另外四个对于 int(在 32 位系统上;在 x64 上,这些数字分别变为 16、8 和 4)。相乘,这意味着这个程序试图在 Node 对象中分配类似 36GB 的内存,这足以解释为什么你不能在 16GB 的系统上运行它。

然而,在 32 位 Windows 上,在您到达那一步之前,您将遇到进程地址空间问题。 (你会在其他 32 位操作系统上遇到类似的情况,因为它在很大程度上是底层硬件的产物。)在 32 位窗口上,每个进程获得 4GB,其中内核需要 2GB ,并且进程本身获得 2GB。您可以通过将操作系统设置更改为 1GB 内核、进程 3GB 来配置它。

后一个限制就是为什么您在用完所有 16GB 物理 RAM 之前就遇到了 OutOfMemoryException。

【讨论】:

  • 感谢您的回复。首先,我需要重新打开问题并将标题改写为“抛出了 'System.OutOfMemoryException' 类型的异常。”
猜你喜欢
  • 2010-09-26
  • 1970-01-01
  • 1970-01-01
  • 2013-01-14
  • 2013-08-28
  • 2015-07-18
相关资源
最近更新 更多