Почему я получаю OutOfMemoryException при попытке создать массив int размером int.MaxValue - PullRequest
4 голосов
/ 18 декабря 2011

Я пытаюсь создать массив, содержащий все возможные положительные целые числа, я попробовал следующий код, и он всегда выбрасывает исключение из памяти.

private int[] AllIntegers()
{
    int[] all = new int[int.MaxValue];

    for (int i = 0; i < int.MaxValue; i++)
    {
        all[i] = i;
    }

    return all;
}

Что я делаю не так? или это вообще невозможно?!

Ответы [ 5 ]

8 голосов
/ 18 декабря 2011

Существует жесткий верхний предел размеров объектов .NET, они не могут превышать 2 гигабайта. Даже в 64-битной операционной системе. Ваш массив намного превышает этот размер.

В 32-разрядной операционной системе вы никогда не приблизитесь к этому пределу, самый большой кусок непрерывной доступной виртуальной памяти составляет около 650 мегабайт. Только при запуске это быстро идет вниз по склону. Это побочный эффект фрагментации адресного пространства, вызванный сочетанием кода и куч в адресном пространстве. Общий объем памяти, который вы можете выделить, близок к 2 гигабайтам, если размер каждого выделения достаточно мал. Не то, к чему вы когда-либо хотели бы приблизиться, случайный сбой программы из-за OOM трудно справиться.

4 голосов
/ 18 декабря 2011

Int.MaxValue = 2 147 483 647, sizeof(int) = 4, поэтому вам потребуется 8 ГБ памяти для выделения этого массива.Исключение означает, что ваша ОС не может выделить этот объем памяти.

== UPDATE ==

MSDN :

При запуске 64-разрядного управляемого приложения в 64-разрядной операционной системе Windows вы можете создать объект объемом не более 2 гигабайт (ГБ).

См. Также: BigArray , обойти ограничение размера массива 2 ГБ

0 голосов
/ 18 декабря 2011

Как говорили другие, вы не можете хранить всю эту информацию в памяти одновременно.Чтобы получить список всех натуральных чисел, просто используйте блок итератора, который одновременно хранит только int в памяти, плюс информацию о состоянии метода:

static void Main (string[] args)
{
    foreach (int i in Program.NaturalNumbers ())
    {
        Console.WriteLine (i);
    }
}

public static IEnumerable<int> NaturalNumbers ()
{
    for (int i = 0; i <= int.MaxValue; i++)
    {
        yield return i;
    }
}
0 голосов
/ 18 декабря 2011

Если вы работаете в 32-битной ОС (в 64-битной ОС это МОЖЕТ измениться), целое число составляет 4 байта (32-битная). Таким образом, int.MaxValue равно 2 ^ 31 (2 ^ 31 со знаком, 2 ^ 31 без знака), поэтому вы пытаетесь выделить массив из 2 ^ 31 целых чисел. Умножив это на 4 байта каждый, вы получите 8589934592 байта, то есть ровно 8 Гбайт.

0 голосов
/ 18 декабря 2011

Вы пытаетесь выделить около 4 * (2 ^ 32 -1) байтов памяти. Это ровно 8 ГБ и, вероятно, больше, чем может предложить ваша система, или, скорее, то, что может выделить ваш процесс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...