.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
Этот метод не работает без следующих настроек.
- Запустить приглашение cmd.exe (важно: запустить как администратор)
- введите bcdedit.exe и запустите
- Посмотрите на параметры "Increuserverva" и нет, тогда напишите следующую инструкцию
- bcdedit/set увеличить увеличить
- и снова шаг 2 и проверьте параметры
Мы добавили эти настройки, и этот блок начался.
if exist "$(DevEnvDir)..\tools\vsvars32.bat" (
call "$(DevEnvDir)..\tools\vsvars32.bat"
editbin /largeaddressaware "$(TargetPath)"
)