Виняток .NET Out Of Memory - використовується 1,3 ГБ, але встановлено 16 ГБ


91

Я отримую виняток Out Of Memory у моїй програмі c #, коли обсяг пам'яті для програми перевищує приблизно 1,3 Гб.

У мене була така сама проблема на 32-бітній машині з 3 Гб пам'яті, і тоді це мало сенс, але тепер я модернізував апаратне забезпечення до 64-бітної машини з 16 Гб пам’яті з високоякісною материнською платою та оперативною пам’яттю, але з відсутністю пам'яті виняток все-таки відбувається після 1,3 ГБ!

Я знаю, що одиничних об’єктів більше 2 Гб немає, а 1,3 все одно менше 2 Гб, тому вбудований ліміт MS 2 Гб на один об’єкт, швидше за все, не є проблемою ...

Здається, існує якийсь перемикач вбивств Windows, коли програма досягає певного порогу використання пам’яті ... Тоді повинен бути спосіб налаштувати це, можливо, у реєстрі?

Будь-яка допомога буде вдячна!


9
Ваша ОС 64 біт також?
fge

9
Навіть якщо ваша ОС 64-бітна, переконайтеся, що ваш процес також 64-бітний (або AnyCPU)
Knowleech

Відповіді:


90

Немає різниці, доки ви не скомпілюєте до тієї самої цільової архітектури. Я вважаю , ви компіляції для 32розрядної архітектури в обох випадках.

Варто згадати, що OutOfMemoryExceptionце також можна підвищити, якщо ви отримаєте 2GBпам'ять, виділену однією колекцією в CLR (скажімо List<T>), як на архітектурах, так 32і на 64бітах.

Щоб отримати користь від пам’яті 64бітової архітектури, вам слід скомпілювати код, націлений на 64бітову архітектуру. Після цього, природно, ваш двійковий файл працюватиме лише на 64бітах, але виграє можливість мати більше місця в оперативній пам'яті.


8
А як щодо AnyCPU?
dtb

1
Так, AnyCPU - це теж варіант, де у вас є можливість залежати від архітектурного коду JIT. Але націлювання на конкретну архітектуру все ще може принести користь у випадках, коли у вас є некеровані (скажімо) ресурси. Я поняття не маю, в чому полягає архітектура OP.
Тігран

4
Я це знав :) - Завдяки Тиграну, я відновив рішення в x64, і виняток пішов.
Пейсмен

63

Як уже зазначалося, компіляція програми в 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).


Дуже дякую. Це працює для мене. Але чи є у нас якісь виявлені проблеми після підвищення ліміту пам’яті до 4 Гб.
Maverick

28

Варто зазначити, що за замовчуванням для компіляції "Any CPU" тепер встановлено прапорець "Prefer 32bit". Будучи налаштованим на AnyCPU, на 64-бітній ОС з 16 Гб оперативної пам'яті все ще може бути встановлено виняток з обсягом пам'яті на 2 Гб, якщо це встановлено.

Prefer32BitCheckBox


2
Це абсолютно вирішило мої проблеми з пам'яттю і врятувало нам
купу

2

Схоже, у вас є 64-бітна арка, прекрасно - але 32-бітна версія середовища виконання .NET та / або 32-бітна версія Windows.

І як такий, адресний простір, доступний для вашого процесу, залишається незмінним, він не змінився від попереднього налаштування.

Оновіть як 64-бітну ОС, так і 64-бітну .NET версію;)


1

Ваша програма працює як 64- або 32-бітний процес? Ви можете перевірити це в диспетчері завдань.

Можливо, він працює як 32-бітний, хоча вся система працює на 64-бітному.

Якщо 32-бітна, це може спричинити стороння бібліотека. Але спочатку переконайтеся, що ваша програма компілює для "Будь-якого процесора", як зазначено в коментарях.


0

Якщо у вас 32-розрядна Windows, цей спосіб не працює без наступних налаштувань.

  1. Запустіть підказку cmd.exe (важливо: Запуск від імені адміністратора)
  2. введіть bcdedit.exe та запустіть
  3. Подивіться на параметри "збільшеннякорисності", і тоді немає наступного твердження
  4. bcdedit / встановити збільшеннякористувача 3072
  5. і знову крок 2 і перевірте параметри

Ми додали ці налаштування, і цей блок розпочався.

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

Докладніше - команда increaseuserva: https://docs.microsoft.com/en-us/windows-hardware/drivers/devtest/bcdedit--set

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.