Управление памятью для интенсивно использующих память приложений

Примечание: Я знаю вопрос Управление памятью в приложении с интенсивной памятью, однако этот вопрос, похоже, касается приложений, которые часто встречаются в то время как мой вопрос касается приложений, предназначенных для того, чтобы потреблять столько физической памяти, сколько безопасно.

У меня есть серверное приложение, которое использует большие объемы памяти для выполнения кэширования и других оптимизаций (думаю, SQL Server). Приложение работает на выделенной машине и поэтому может (и должно) потреблять столько памяти, сколько захочет/может, чтобы ускорить и увеличить пропускную способность и время отклика, не опасаясь воздействовать на другие приложения в системе.

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

Некоторые предположения:

  • Приложение работает на выделенной машине
  • Требования к памяти приложения превышают физическую память на компьютере (то есть, если дополнительная память была доступна для приложения, она всегда сможет использовать эту память, чтобы каким-то образом улучшить время отклика или пропускную способность)
  • Управление памятью эффективно управляется таким образом, что фрагментация памяти не является проблемой.
  • Приложение знает, какая память может быть безопасно освобождена, и какая память должна быть освобождена сначала для наименьшего влияния на производительность.
  • Приложение работает на компьютере под управлением Windows

Мой вопрос - как я должен обрабатывать выделения памяти в таком приложении? В частности:

  • Как я могу предсказать, не произойдет ли распределение памяти?
  • Должен ли я оставить определенный объем свободной памяти, чтобы гарантировать, что операционные системы ОС остаются отзывчивыми (и не так негативно влияют на производительность приложений), и как я могу узнать, сколько памяти есть?

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

Я разработчик С#, однако я надеюсь, что базовые понятия для любого такого приложения одинаковы независимо от языка.

Ответ 1

В linux процент использования памяти делится на следующие уровни.

0 - 30% - без обмена 30-60% - обмен только грязными страницами 60 - 90% - своп чистых страниц, также основанных на политике LRU.

90% - вызывают убийцу OOM (без памяти) и убивают процесс, потребляющий максимальную память.

проверьте это - http://linux-mm.org/OOM_Killer

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

Один из способов прекратить потреблять больше памяти - это переспать и дать больше времени для потоков очистки памяти.

Ответ 2

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

Для правильного управления памятью звучит утомительно, но применяется здравый смысл, например предложение using для обеспечения того, чтобы объект был удален. Вы можете поместить одного обработчика в ловушку OutOfMemory Exception, но это неудобно, поскольку, если у программы закончилась нехватка памяти, программа просто захватывает и выкапывает, или она должна терпеливо ждать, пока GC удар, снова определяя, что это сложно.

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

В сущности, в то время как отличный вопрос, я думаю, вам не стоит беспокоиться об этом и оставить его в .NET CLR для обработки выделения/фрагментации памяти, поскольку он, кажется, выполняет довольно хорошую работу.

Надеюсь, это поможет, С наилучшими пожеланиями, Том.

Ответ 3

Ваш вопрос напоминает мне о старой дискуссии "Так что же случилось с программированием 1975 года?" . Архитектор varnish-cache утверждает, что вместо того, чтобы сообщать ОС, чтобы уйти с пути и управлять всей памятью самостоятельно, вам следует скорее сотрудничать с ОС и дать понять, что вы собираетесь делать с памятью.

Например, вместо простого чтения данных с диска вы должны использовать файлы с отображением памяти. Это позволяет ОС применять свой алгоритм LRU для записи данных на диск, когда память становится недостаточной. В то же время, пока есть достаточно памяти, ваши данные останутся в памяти. Таким образом, ваше приложение может потенциально использовать всю память, не рискуя быть убитым.