OutOfMemoryException при заполнении MemoryStream: выделение 256 МБ на 16 ГБ системе

Я запускаю следующий метод на моем сервере IIS разработки (из VS2010 IDE) на 64-разрядной машине с Windows 7 с 16 ГБ установленной оперативной памяти:

public static MemoryStream copyStreamIntoMemoryStream(Stream stream) { long uiLen = stream.Length; byte[] buff = new byte[0x8000]; int nSz; MemoryStream ms = new MemoryStream(); try { while ((nSz = stream.Read(buff, 0, buff.Length)) != 0) { ms.Write(buff, 0, nSz); } } finally { Debug.WriteLine("Alloc size=" + ms.Length); } return ms; } 

и я получаю System.OutOfMemoryException в этой строке:

 ms.Write(buff, 0, nSz); 

Это выбрано, когда выделено 268435456 байтов:

Alloc size = 268435456

который равен 0x10000000 или 256 МБ. Поэтому мне интересно, есть ли какие-то глобальные настройки, которые мне нужно настроить, чтобы они работали?

Вот скриншот настроек конфигурации для проекта: введите описание изображения здесь

2 Solutions collect form web for “OutOfMemoryException при заполнении MemoryStream: выделение 256 МБ на 16 ГБ системе”

Короткий ответ – сервер dev – это 32-битный процесс.

Длинный ответ за «почему всего 256 МБ?»

Прежде всего, давайте разобраться, как это работает.

MemoryStream имеет внутренний байт [] для хранения всех данных. Он не может предсказать точный размер этого буфера, поэтому он просто инициализирует его с некоторым начальным значением.

Свойства Position и Length не отражают фактический размер буфера – они являются логическими значениями, отражающими количество байтов и легко могут быть меньше фактического размера физического буфера.

Когда этот внутренний буфер не может вместить все данные, он должен быть «изменен», но в реальной жизни это означает создание нового буфера в два раза по сравнению с предыдущим, а затем копирование данных из старого буфера в новый буфер.

Итак, если длина вашего буфера составляет 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 – все в порядке.

Надеюсь это поможет.

Если вы используете сервер разработки VS по умолчанию, вы запускаете код в процессе x86 / 32 бит. Если вы используете полный IIS – скорее всего, в IIS, в частности, AppPool настроен на работу в x86 (32-разрядный режим) и, как результат, имеет очень ограниченное адресное пространство (2 ГБ, если вы не отметили свое приложение как Large Address Aware).

В случае IIS убедитесь, что вы настроили опросы пользователей для запуска x64 (не уверены, что такое значение по умолчанию). Убедитесь, что для вашего кода задано значение «AnyCPU» или «x64».

Для автономных приложений C # – по умолчанию они скомпилированы с x86 или AnyCPU / Prefer x86 – изменят целевую платформу на x64.

Чтобы получить поддержку x64 для IIS, вы можете либо установить полный IIS, либо установить IIS Express 8.0 (7.5, который поставляется с Windows 7, всего 32 бит) из Download IIS 8.0 Express .

Боковые заметки:

  • Если вы только что установили полный IIS, обязательно обновите свое решение, чтобы использовать IIS для хоста сайта.
  • У меня нет машины для проверки необходимости каких-либо дополнительных шагов для поддержки x64 для IIS Express. Проверьте этот вопрос. Невозможно получить бета-версию IIS Express 8 для запуска веб-сайта в виде 64-битного процесса, поскольку это может дать вам некоторые идеи.
  • Вы также можете попытаться создать свою собственную версию сервера разработки x64 на основе предложений здесь: совместима ли с Visual Studio 2010 WebDev WebServer (Cassini) 64-разрядная совместимость?
  • Определение использования памяти объектами?
  • Вызывается ли сборщик мусора Dispose ()?
  • Как реализуется malloc () внутри?
  • java.lang.OutOfMemoryError: размер растрового изображения превышает бюджет VM - Android
  • Общая страtagsя для устранения утечки памяти Java?
  • Циркулярные ссылки Причина утечки памяти?
  • Как контролировать использование компьютера, памяти и диска компьютера в Java?
  • g ++ размер массива без предупреждения?
  • По умолчанию Xmxsize в Java 8
  • Как загрузить большой файл xlsx с помощью Apache POI?
  • Определить размер кучи приложения в Android
  • Interesting Posts

    Угловые случаи, неожиданные и необычные MATLAB

    Кнопка добавления / вычитания Excel VBA

    C ++ STL vector vs array в реальном мире

    Как добавить «метро», смотрящую плитку для настольного приложения?

    Как безопасно отправлять пароль через HTTP?

    Твердые конденсаторы лопнут, ПК кажется прекрасным, насколько безопасно продолжать его использовать?

    Не удается найти правильный Ubuntu Server ISO для VirtualBox

    Почему вы не должны расширять JFrame и другие компоненты?

    Почему порядок циклов влияет на производительность при итерации по 2D-массиву?

    Почему объекты одного classа имеют доступ к личным данным друг друга?

    Самый быстрый способ вычисления абсолютного значения с помощью SSE

    JSF не поддерживает проверку кросс-поля, есть ли обходной путь?

    Как сжать .pdfs в Word 2007?

    Любые рекомендации для бесшовной «надежной копии файлов» для Windows?

    Обновление текстового документа MS из двух других документов

    Давайте будем гением компьютера.