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 МБ. Поэтому мне интересно, есть ли какие-то глобальные настройки, которые мне нужно настроить, чтобы они работали?

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

Короткий ответ – сервер 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-разрядная совместимость?
  • Слабые справочные преимущества
  • Будет ли `char` всегда всегда - всегда иметь 8 бит?
  • С ARC, что лучше: alloc или autorelease инициализаторы?
  • Как я могу назвать оригинальный «оператор new», если я его перегрузил?
  • «Ошибка при отсутствии памяти (Java)» при использовании пакетов R и XLConnect
  • что использует MemoryFile в android
  • Явное освобождение памяти в c #
  • Как установить максимальное использование памяти для JVM?
  • Как его срок службы возвращаемого значения распространяется на область действия вызывающей функции, когда она привязана к константной ссылке в вызывающей функции?
  • Как контролировать использование компьютера, памяти и диска компьютера в Java?
  • Что вызывает fragmentацию памяти в .NET.
  • Interesting Posts

    Генерировать случайные числа после нормального распределения в C / C ++

    Drawable-hdpi, Drawable-mdpi, Drawable-ldpi Android

    Как использовать ключи f-1 – f12 без нажатия клавиши FN в Windows 7 с помощью bootcamp на Macbook Pro?

    Как перемещаться по IEnumerable пакетами

    Бит-поля в C #

    В bash, как я могу проверить, начинается ли строка с некоторого значения?

    почему явным образом удаляю конструктор?

    Извлечение последних n символов из строки в R

    Как программно изменить контрастность растрового изображения в андроиде?

    Mac Text Editor (с списком функций)

    Не удалось подключиться к PPTP VPN в Ubuntu: отключен плагин VPN: 1

    Как настроить профиль пользователя при использовании django-allauth

    Приложение C # Windows Forms – обновление GUI из другого streamа и classа?

    Сила сигнала Wifi и подключение к Интернету медленны

    Могу ли я установить неподписанные драйверы Windows для работы без тестового режима или отключения подписи драйвера и без покупки сертификата подписи кода?

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