Ответ 1
Короткий ответ - сервер dev - это 32-битный процесс.
Длинный ответ для "почему всего 256 Мб?"
Прежде всего, дайте понять, как это работает.
MemoryStream имеет внутренний буфер [], чтобы сохранить все данные. Он не может предсказать точный размер этого буфера, поэтому он просто инициализирует его с некоторым начальным значением.
Свойства позиции и длины не отражают фактический размер буфера - они являются логическими значениями, отражающими количество байтов и легко могут быть меньше фактического размера физического буфера.
Если этот внутренний буфер не может вместить все данные, он должен быть "изменен", но в реальной жизни это означает создание нового буфера в два раза по размеру предыдущего, а затем копирование данных от старого буфера до нового буфера.
Итак, если длина вашего буфера составляет 256 Мб, и вам нужны новые данные, которые нужно записать, это значит, что .Net нужно найти еще один блок данных 512 МБ - все остальное на месте, поэтому куча должна быть в не менее 768 Мб в момент выделения памяти при получении OutOfMemory.
Также обратите внимание, что по умолчанию ни один объект, включая массивы, в .Net не может иметь размер более 2 ГБ.
Итак, вот образец, который имитирует происходящее:
byte[] buf = new byte[32768 - 10];
for (; ; )
{
long newSize = (long)buf.Length * 2;
Console.WriteLine(newSize);
if (newSize > int.MaxValue)
{
Console.WriteLine("Now we reach the max 2Gb per single object, stopping");
break;
}
var newbuf = new byte[newSize];
Array.Copy(buf, newbuf, buf.Length);
buf = newbuf;
}
Если он построен в x64/AnyCPU и запускается с консоли - все в порядке.
Если он построен на x86 - он не работает в консоли.
Если вы положили его на страницу "Page_Load", встроенную в x64 и открытую с веб-сервера VS.Net, это не сработает.
Если вы делаете то же самое с IIS - все в порядке.
Надеюсь, что это поможет.