Могу ли я сказать Linux, чтобы не менять память определенных процессов?

Есть ли способ сказать Linux, что он не должен заменять память определенных процессов на диск?

Это приложение Java, поэтому в идеале я надеюсь на способ сделать это из командной строки.

Я знаю, что вы можете установить глобальную swappiness на 0, но является ли это мудрым?

Ответ 1

Вы можете сделать это через системный вызов mlockall (2) под Linux; это будет работать на весь процесс, но прочитайте о аргументе, который вам нужно передать.

Вам действительно нужно вытащить все это в ядре? Если это приложение java, вы, вероятно, заблокируете всю JVM в ядре. Я не знаю метода командной строки для этого, но вы можете написать тривиальную программу для вызова fork, вызвать mlockall, затем exec.

Вы также можете посмотреть, соответствует ли одно из уведомлений шаблона доступа в madvise (2) вашим потребностям. Консультирование подсистемы VM о лучшей стратегии поискового вызова может работать лучше, если она применима для вас.

Обратите внимание, что давным-давно в SunOS появился механизм, похожий на madvise, называемый vadvise (2).

Ответ 3

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

Ответ 4

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

Ответ 5

За исключением чрезвычайно необычных обстоятельств, задание этого вопроса означает, что вы делаете это неправильно (tm).

Серьезно, если Linux хочет поменять местами, и вы пытаетесь сохранить свой процесс в памяти, тогда вы ставите необоснованный спрос на ОС. Если ваше приложение так важно, то 1) купите больше памяти, 2) удалите другие приложения/демоны с компьютера или посвятите машину вашему приложению и/или 3) инвестируйте в действительно быструю дисковую подсистему. Эти шаги являются разумными для важного приложения. Если вы не можете их оправдать, вы, вероятно, не сможете оправдать электропроводку и голодать другие процессы.

Ответ 6

Существует класс приложений, в котором вы никогда не захотите их менять. Одним из таких классов является база данных. Базы данных будут использовать память как кеши и буферы для своих дисковых областей, и совершенно не имеет смысла, что они когда-либо заменяются. В конкретной памяти могут храниться некоторые релевантные данные, которые не нужны в течение недели, до одного дня, когда клиент запрашивает ее. Без кэширования/замены база данных просто найдет соответствующую запись на диске, которая будет довольно быстрой; но с заменой, ваше обслуживание может внезапно занять много времени, чтобы ответить.

mysqld содержит код для использования системного вызова memlock. В Linux, как минимум, 2.6.9, этот системный вызов будет работать для процессов без полномочий root, которые имеют возможность CAP_IPC_LOCK [1]. При использовании memlock() процесс должен работать в пределах предела LimitMEMLOCK. [2]. Одна из (немногих) хороших вещей о systemd заключается в том, что вы можете предоставить mysqld эти возможности, не требуя специальной программы. Если также можно установить rlimits, как вы ожидаете, с помощью ulimit. Вот файл override для mysqld, который выполняет требуемые шаги, в том числе несколько других, которые могут потребоваться для процесса, такого как база данных:

[Service]
# Prevent mysql from swapping
CapabilityBoundingSet=CAP_IPC_LOCK

# Let mysqld lock all memory to core (don't swap)
LimitMEMLOCK=-1 

# do not kills this process if low on memory
OOMScoreAdjust=-900 

# Use higher io scheduling
IOSchedulingClass=realtime    

Type=simple    
ExecStart=
ExecStart=/usr/sbin/mysqld --memlock $MYSQLD_OPTS

Примечание Стандартное сообщество mysql в настоящее время поставляется с Type=forking и добавляет --daemonize в параметр службы в строке ExecStart. Это по своей сути менее устойчиво, чем вышеупомянутый метод.

ОБНОВЛЕНИЕ Я не на 100% доволен этим решением. После нескольких дней работы я заметил, что процесс по-прежнему имел огромное количество свопов! Изучая /proc/XXXX/smaps, я отмечаю следующее:

  • Самый большой вкладчик swap - из сегмента стека! 437 МБ и колебания. Это создает очевидные проблемы с производительностью. Он также указывает на утечку памяти на основе стека.
  • Есть ноль заблокированных страниц. Это означает, что параметр memlock в MySQL (или Linux) не работает. В этом случае это не имеет большого значения, потому что MySQL не может блокировать стек.

Ответ 7

Почему вы хотите это сделать?
Если вы пытаетесь увеличить производительность этого приложения, вы, вероятно, ошибетесь. ОС поменяет процесс увеличения объема памяти для дискового кэша - даже если есть свободная оперативная память, ядро ​​лучше знает (по-разному, ребята samrt, которые писали планировщик, знают лучше).
Если у вас есть процесс, который требует отклика (он поменяется, пока он не используется, и вам нужно его быстро перезапустить), то с ним справится высокий приоритет, mlock или использование ядра реального времени.