2011-01-27 4 views
14

Мне нужно создать довольно большой двойной массив 12000ish x 55000ish. К сожалению, я получаю исключение из памяти. Я использовал для разработки на Java и мог изменять настройки памяти. Возможно ли это с C# или это просто невозможно? Я использую VS 2008.OutOfMemoryException при объявлении большого массива

+1

A * довольно * большой массив? :) – Groo

+0

Я бы предложил вам рассмотреть структуру данных «из основной памяти» (т. Е. Базу данных). Почему вы должны хранить такой большой двойной массив? – bitxwise

+0

Я тоже посмеялся над выбором слова «честно». –

ответ

25

Каждый double имеет 8 байтов, поэтому вы пытаетесь выделить один массив размером чуть более 5 ГБ. CLR имеет ограничение на объект около 2 ГБ IIRC, даже для 64-битной CLR. Другими словами, это не общий объем доступной памяти, это проблема (хотя, очевидно, у вас будут проблемы, если у вас нет хватает памяти), но размер каждого объекта.

Я предлагаю вам разбить его на меньшие массивы, возможно, за фасадом какого-то описания. Я не верю, что есть какой-то способ обхода этого предела для одного массива.

EDIT: Вы могли пойти на массив массивов - он же в зубчатого массива:

double[][] array = new double[12000][]; 
for (int i = 0; i < array.Length; i++) 
{ 
    array[i] = new double[55000]; 
} 

это будет приемлемо для вас?

(Вы не можете использовать прямоугольный массив (double[,]), поскольку это будет иметь ту же проблему, размер каждого-объекта.)

+0

+1 для фактической разработки размера. Я не должен быть таким ленивым – Ian

+0

ОК спасибо. поэтому он не мог использовать виртуальную память? – cs0815

+1

Вместо одного массива двойников, я думаю, он имеет в виду 2D-массив – bitxwise

0

Ну, либо вы потеряли память (закройте некоторые программы), либо вы достигли предела распределения памяти (около 2 ГБ), эта память должна быть смежным блоком. Вы можете использовать 64-битную машину, в этом случае у вас будет больше доступной памяти, или я думаю, что вы можете сделать приложение большим адресом осведомленным (поиск в Google расскажет вам, как это сделать, если это возможно в этом случае).

Поверьте, вы добавляете ключ/3GB в файл Boot.ini для понимания большого адреса.

9

Поскольку вы не можете создавать объекты размером более 2 Гб, вы можете попробовать использовать MemoryMappedFile для работайте с куском памяти требуемого размера.

 

var data = MemoryMappedFile.CreateNew("big data", 12000L * 55000L); 
var view = data.CreateViewAccessor(); 
var rnd = new Random(); 

for (var i = 0L; i < 12000L; ++i) 
{ 
    for (var j = 0L; j < 55000L; ++j) 
    { 
     var input = rnd.NextDouble(); 
     view.Write<double>(i * 55000L + j, ref input); 
    } 
} 
 
4

При условии, что ваш общий объем памяти достаточно, вы можете предотвратить Из исключений памяти в результате фрагментации LOH, создавая кучу мелких массивов, и упаковка их в одном IList<T>, или какой-либо другой индексируемой интерфейс.

Вот ссылка, которая описывает его:

BigArray<T>, getting around the 2GB array size limit

Кредиты: this post (C# chunked array).

Смежные вопросы