OutOfMemoryException с помощью gcAllowVeryLargeObjects
Я использую BinarySerializer с довольно большим (хотя и не очень глубоким) графиком элементов. У меня 8 ГБ оперативной памяти, поддерживаемой 12Gig swap, и я получаю исключение OutOfMemoryException при сериализации, которое ожидается (возможно, график может приближаться или превышать 2 ГБ).
Однако, когда я использую gcAllowVeryLargeObjects, это не лучше, я все равно получаю одно и то же исключение, и я определенно работаю над тем, что должно храниться в памяти (по крайней мере, с помощью swap).
Есть ли что-нибудь, что я могу сделать, чтобы поддерживать сериализацию этого/способ получить тот же набор функций, но получить результат в chuck можно?
В моем коде сериализации ничего особенного нет:
public static byte[] Serialize(this object o)
{
var ms = new MemoryStream();
var bf = new BinaryFormatter();
bf.Serialize(ms, o);
ms.Position = 0;
return ms.ToArray();
}
Объект, который я сериализую, содержит массивы элементов, которые сами содержат массив и т.д., но сам полный граф не является "тем" большим (это результат индексирования данных, который у источника уже составляет около 1 ГБ в размер).
Это не связано с фрагментацией GC (уплотнение большой кучи не помогло).
Ответы
Ответ 1
По умолчанию AnyCPU работает как 32-битный процесс как на ОС x86, так и на x64. Таким образом, даже с gcAllowVeryLargeObjects
, установленным на ОС x64, вы запускаете ограничение на 4 ГБ адресного пространства (2 ГБ на x86).
Чтобы изменить снимите флажок "Предпочтительно 32-битное" свойство свойств решения → вкладка "build".
Подробности и история можно найти в следующем ответе: Какова цель "Предпочтительно, чтобы 32-разрядная" в Visual Studio 2012 и как это работает?