Проблема потребления памяти CLR - PullRequest
5 голосов
/ 10 ноября 2010

Одна из проблем с CLR - это крайне плохое поведение при нехватке ОЗУ (когда часть памяти управляемого процесса выгружается, это приводит к полной остановке всей системы, даже экран Ctrl-Alt-Del может 'Я полагаю, причина в том, что GC пытается построить график достижимых объектов и пытается просканировать всю память процесса, вызывая массовые операции ввода / вывода страниц).
Это создает проблему для моей программы .NETПотому что это может потреблять много оперативной памяти, когда входные данные огромны.

Я бы предпочел показывать пользователю сообщение "недостаточно памяти", а не полностью зависать его системе ^ _ ^
Есть ли способ добиться этого?

Ответы [ 4 ]

3 голосов
/ 10 ноября 2010

С помощью MemoryFailPoint вы можете сказать .NET, что вам понадобится определенный объем памяти. Проблема, однако, в том, что даже в этой системе есть пространство подкачки.

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

У меня естьпредложение. У вас может быть параметр конфигурации с максимально допустимым объемом памяти, который будет использоваться приложением?При этом вы можете:

  1. Попытаться выяснить, сколько ресурсов использует ваше приложение, например, на основе сетевого подключения (если ваше приложение является сетевым сервером) и регулировать количество подключений на основена максимальное потребление памяти, или

  2. Может быть запущен второй поток, который проверяет каждые 10 секунд или минут общего потребления памяти с помощью GC.GetTotalMemory() и начинает отклонять соединения (снова,если ваше приложение является сетевым сервером), как только вы достигнете этого максимума.

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

2 голосов
/ 10 ноября 2010

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

Раньше было много исследований по написанию GC, которые могли бы справляться с подкачкой, ноЯ ожидаю, что они никогда не будут поставляться, так как оперативная память сейчас настолько велика.(Основной идеал состоял не в том, чтобы собирать объекты, которые выгружаются, а в том, чтобы пытаться собрать все объекты на странице непосредственно перед тем, как ОС выгружает их. Но вам нужно знать все объекты, на которые может указывать страницаout object.)

Вы можете использовать массивы структур, а затем передавать индексы, чтобы уменьшить количество имеющихся у вас объектов и, следовательно, количество указателей, которым должен следовать GC,Это имеет смысл только в том случае, если в ОЗУ имеется МНОГО данных того же типа, что и вам.

1 голос
/ 21 ноября 2010

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

Чтобы создавать объекты заданий из .NET, вы должны использовать вызовы PInvoke к Win32 API.Эта статья о CodeProject объясняет процедуру.

0 голосов
/ 11 октября 2011

В IIS размещайте процесс и используйте элементы управления памятью в IIS, чтобы ограничить объем используемой памяти. Надеемся, что это заставит GC чаще и сведет к минимуму необходимость длительной сессии GC. Я полагаю, что такое поведение связано с тем, как ваше приложение использует память из поколения в поколение, как, например, большое количество небольших объектов, которые 1) долговечны и 2) перемещаются в памяти.

Другие ссылки на аналогичные проблемы и решения по управлению памятью .NET / CLR

Настройка использования ОЗУ .NET CLR
Ограничение использования памяти .Net CLR
Виртуальная и физическая память / OutOfMemoryException
Предотвращение исключения OutOfMemory с помощью GC.AddMemoryPressure ()?
Принудительная сборка мусора массивов, C #
примеры узких мест сборки мусора
Подавление сборки мусора в C #
как профилировать .net сборщик мусора?

В случае, если вы используете кучу больших объектов (LOH)

Коллекции .NET и куча больших объектов (LOH)
Фрагментация кучи больших объектов

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...