Память, общий вопрос
Ситуация следующая. Нужно выбелить большие объемы данных. Допустим, массив int'ов из миллиарда элементов. Оперативной памяти в компьютере - 8ГБ.
Считаем, сколько это, миллиард интов
1000000000 * 4 = 4000000000 байт = 3906250 КБайт = 3814,7 МБайт = 3,73 Гбайт
+ еще нужно немного памяти на организацию всего это в массив. Должно уместиться.
Но на строке
Вылетает с сообщением OutOfMemoryException.
Вроде как массивы могут индексироваться типом int, а значит должны допускать индекс int.MaxValue. А это больше 2 миллиардов.
Я провел небольшой эксперимент, итогом которого стало:
1) Можно выделить память под массив из 100 миллионов элементов.
2) Это можно сделать 4 раза подряд.
3) На пятом опять получаю исключение.
Вопрос можно назвать философским, потому что вот его краткий итог: ПОЧЕМУ так происходит? Я явно что-то не знаю о работе стека и кучи памяти =)
В свойствах системы пишется: "Тип системы: 64-разрядная операционная система"
Такой большой непрерывный кусок памяти выделить очень сложно. В системе-то свободная память есть, но она фрагментирована. Скорей всего.
Кстати, вот было обсуждение: http://rsdn.ru/forum/dotnet/4277317.flat.aspx#4277317
В .NET есть ограничение на максимальный размер объекта (массивы это тоже объекты) - это 2ГБ. CLR просто не позволит создать объект больше.
В x64 процессе найти непрерывный блок виртуальных адресов такого размера - сущий пустяк. Об отображении этих виртуальных адресов на физические будет заботиться менеджер памяти ОС и процессор.
А почему я тогда последовательно создаю объекты(в моем случае массивы из 100 миллионов элементов), заведомо меньшие 2ГБ (не более 400 метров), но при создании пятого такого объекта вылетает exception?
Потому что в CLR 2.0 есть некое внутреннее ограничение на размер кучи больших объектов. В CLR 4.0 этого ограничения либо нет, либо оно значительно слабее.