.NET Out Of Memory Exception - используется 1,3 ГБ, но установлено 16 ГБ

Я получаю исключение Out Of Memory в моем приложении С#, когда использование памяти для приложения превышает 1,3 ГБ.

У меня была такая же проблема на 32-битной машине с 3 ГБ памяти, и тогда это имело смысл, но теперь я обновил аппаратное обеспечение до 64-разрядной машины с 16 ГБ оперативной памятью с материнской платой высокого класса и оперативной памятью, но Исключение из памяти по-прежнему происходит после 1.3 ГБ!

Я знаю, что нет никаких объектов на 2 ГБ, а 1,3 - меньше 2 ГБ, так что встроенный предел MS 2GB на одном объекте вряд ли будет проблемой...

Похоже, что есть какой-то тип kill-switch windows, когда приложение достигает определенного порога использования памяти... Тогда должен быть способ настроить это в реестре, возможно?

Любая помощь будет принята с благодарностью!

Ответ 1

Нет никакой разницы, пока вы не скомпилируете одну и ту же целевую архитектуру. я предположим, который вы компилируете для архитектуры бит 32 в обоих случаях.

Следует отметить, что OutOfMemoryException также может быть поднят, если вы получите 2GB памяти, выделенной одним в CLR (скажем List<T>) на обеих архитектурах 32 и 64 бит.

Чтобы иметь возможность пользоваться преимуществами памяти в архитектуре бит 64, вы должны скомпилировать свой код с таргетингом на битовую архитектуру 64. После этого, естественно, ваш двоичный файл будет работать только на бит 64, но выиграет от возможности иметь больше свободного места в ОЗУ.

Ответ 2

Как уже упоминалось, компиляция приложения в x64 дает вам гораздо более доступную память.

Но в том случае, когда нужно построить приложение на x86, есть способ повысить лимит памяти от 1,2 до 4 ГБ (что является фактическим пределом для 32-битных процессов):

В папке VC/bin установочного каталога Visual Studio должен быть файл editbin.exe. Поэтому при установке по умолчанию я нахожу его под

C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\editbin.exe

Чтобы программа работала, возможно, сначала вы должны выполнить vcvars32.bat в том же каталоге. Тогда a

editbin /LARGEADDRESSAWARE <your compiled exe file>

достаточно, чтобы ваша программа использовала ОЗУ 4 ГБ. <your compiled exe file> - это exe, сгенерированный VS при компиляции вашего проекта.

Если вы хотите автоматизировать это поведение каждый раз, когда вы компилируете свой проект, используйте следующее событие Post-Build для выполненного проекта:

if exist "$(DevEnvDir)..\tools\vsvars32.bat" (
   call "$(DevEnvDir)..\tools\vsvars32.bat"
   editbin /largeaddressaware "$(TargetPath)"
)

Sidenote: То же самое можно сделать с помощью devenv.exe, чтобы Visual Studio также использовала 4 ГБ ОЗУ вместо 1,2 ГБ (но сначала создайте резервную копию старого devenv.exe).

Ответ 3

Стоит отметить, что по умолчанию для компиляции "Любой процессор" теперь проверяется флажок "Предпочтительный 32-битный". Будучи настроенным на AnyCPU, на 64-битной ОС с 16-гигабайтной оперативной памятью все равно может попасть в исключение из памяти на 2gb, если это отмечено.

Prefer32BitCheckBox

Ответ 4

Похоже, у вас есть 64-битная арка, отлично, но 32-разрядная версия среды выполнения .NET и/или 32-разрядная версия Windows.

И как таковое, адресное пространство, доступное вашему процессу, остается тем же, оно не изменилось с вашей предыдущей настройки.

Обновление до 64-битной ОС и 64-разрядной версии .NET;)

Ответ 5

Работает ли ваше приложение как 64-битный или 32-битный процесс? Вы можете проверить это в диспетчере задач.

Это может быть, он работает как 32 бит, хотя вся система работает на 64-битной версии.

Если 32bit, сторонняя библиотека может вызвать это. Но сначала убедитесь, что ваше приложение компилируется для "Любой процессор", как указано в комментариях.

Ответ 6

Этот метод не работает без следующих настроек.

  1. Запустить приглашение cmd.exe (важно: запустить как администратор)
  2. введите bcdedit.exe и запустите
  3. Посмотрите на параметры "Increuserverva" и нет, тогда напишите следующую инструкцию
  4. bcdedit/set увеличить увеличить
  5. и снова шаг 2 и проверьте параметры

Мы добавили эти настройки, и этот блок начался.

if exist "$(DevEnvDir)..\tools\vsvars32.bat" (
   call "$(DevEnvDir)..\tools\vsvars32.bat"
   editbin /largeaddressaware "$(TargetPath)"
)