Максимальная память, которую может выделить процесс .NET - PullRequest
26 голосов
/ 01 июня 2009

Какой максимальный объем памяти, который сборщик мусора может выделить для процесса .NET? Когда я компилирую в x64, Process.GetCurrentProcess.MaxWorkingSet возвращает около 1,4 ГБ, но когда я компилирую в AnyCPU (x64), возвращается то же число. Для x64 это должно быть больше похоже на значение «Limit», которое отображается в диспетчере задач. Как я могу получить правильный номер, который будет вызывать OutOfMemory-Exceptions при превышении во всех случаях?

Некоторые примеры того, что должен возвращать метод:

1) Конфигурация машины: x64-Windows, 4 ГБ физической памяти, файл подкачки 4 ГБ
-Как 64-битный процесс: 8 ГБ
-Как 32-битный процесс: 1,4 ГБ

2) Конфигурация машины: x64-Windows, 1 ГБ физической памяти, файл подкачки 2 ГБ
-Как 64-битный процесс: 3 ГБ
-Как 32-битный процесс: 1,4 ГБ

3) Конфигурация машины: x32-Windows, физическая память 4 ГБ, файл подкачки 4 ГБ
-Как 64-битный процесс: не произойдет
-Как 32-битный процесс: 1,4 ГБ

4) Конфигурация машины: x32-Windows, 512 МБ физической памяти, файл подкачки 512 МБ
-Как 64-битный процесс: не произойдет
-Как 32-битный процесс: 1,0 ГБ

Ответы [ 2 ]

17 голосов
/ 01 июня 2009

В Windows можно настроить выделение большего пространства для файлов подкачки по запросу или по запросу .
Объекты заданий могут предотвратить потребление более определенного объема памяти.
Фрагментация кучи и порождающая ее природа (плюс необходимость помещать большие вещи в кучу больших объектов)

Все это означает, что жесткий предел в действительности мало используется и означает, что ответить на вопрос «сколько памяти я могу выделить теоретически» довольно сложно, чем вы думаете.

Так как любой человек задает вопрос , этот вопрос, вероятно, пытается что-то сделать неправильно и должен перенаправить вопрос на что-то более полезное.

Что вы пытаетесь сделать, что может вызвать такой вопрос?

"Я просто хочу знать, когда текущая загрузка памяти процесса может стать проблематичной поэтому я могу выполнять такие действия, как освобождение некоторых элементов пользовательского кэша. "

правый. это гораздо более податливый вопрос.

Два решения в порядке сложности:

  1. Заставьте свои кеши использовать WeakReferences
    • Это означает, что система будет освобождена для вас почти магическим образом, но вы будете иметь небольшой контроль над такими вещами, как политика замены
    • это зависит от того, что кэшированные данные намного больше, чем ключ, и накладных расходов из-за слабой ссылки
  2. Зарегистрироваться для уведомлений о сборках мусора
    • Это позволяет вам контролировать освобождение вещей.
    • Вы полагаетесь на систему, имеющую соответствующий максимальный размер для поколений ГХ, для перехода в устойчивое состояние может потребоваться некоторое время.

Очки на заметку. Неужели действительно дешевле поддерживать этот массивный кеш (выходящий на диск по звукам), чем пересчитывать / повторно запрашивать данные.
Если ваш кеш имеет плохую локализацию между обычно / последовательно запрашиваемыми элементами, тогда много усилий будет потрачено на перелистывание данных. Кэш меньшего размера с эффективной настроенной политикой переназначения дает хорошие шансы значительно лучше работать (и с гораздо меньшим влиянием на другие работающие программы)

В качестве отступления: в .Net ни один объект переменного размера (строки, массивы) не может иметь размер более 2 ГБ из-за ограничений основных структур CLR для управления памятью. (и от этого выиграет любое из указанных выше решений)

3 голосов
/ 01 июня 2009

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

Теоретически, процесс x64 может выделять ОЗУ (etabytes?) ОЗУ, я думаю - то есть, МНОГО. Но если вы это сделаете, ваша машина должна начать пейджинг как сумасшедшая и вообще умереть.

В 32-битном режиме все было иначе, так как вы не могли выделить больше 1 ГБ ОЗУ в ЛЮБОМ процессе в Windows (да, есть способы обойти это, но это не красиво). На практике это примерно 7-800 мг на процесс .NET, так как .NET зарезервировал некоторое пространство.

В любом случае, в 32-разрядной версии самое большее, что вы можете использовать, - это 3 ГБ - ОС резервирует для себя 1 ГБ виртуального пространства.

В 64 битах это должно быть 2 ^ 64, что является большим числом, но http://en.wikipedia.org/wiki/X86-64 говорит, что это 256 ТБ виртуального пространства и 1 ТБ РЕАЛЬНОЙ ОЗУ. В любом случае, это намного больше, чем у вас, вероятно, на вашем компьютере, поэтому он попадет в файл подкачки.

с 64-разрядной ОС и 64-разрядной средой выполнения, Приложения на базе .NET 2.0 теперь могут использовать в 500 раз больше памяти для данных такие как серверные кеши.

Это тоже хорошая информация http://www.theserverside.net/tt/articles/showarticle.tss?id=NET2BMNov64Bit

Кстати, если вы работаете на x64-машине (то есть на x64-машине + x64-ОС), компиляция для AnyCPU и x64 делает то же самое - он работает в режиме x64. Разница лишь в том, что вы используете AnyCPU vrs x86:

  • x64 OS / .NET, AnyCpu: x64 app
  • x64 OS / .NET, x64: приложение x64
  • x64 OS / .NET, x32: x32 приложение (x64 .NET Framework как установленная версия Fx ОБА x32 и x64)

  • x32 OS / NET, AnyCPU: приложение x32

  • x32 OS / .NET, x64: КРЫШКА И ОЖОГ РЕБЕНКА! (на самом деле, он просто изящно умирает)
  • x32 OS / .NET, x32: приложение x32.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...