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

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

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

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


person sanity    schedule 23.02.2009    source источник
comment
Раньше Unix уважал липкий бит, если вы выполняли chmod + S в приложении, но я не думаю, что это больше работает.   -  person Paul Tomblin    schedule 23.02.2009
comment
Извините, я имел в виду chmod + t, но я только что посмотрел, и Linux игнорирует липкий бит.   -  person Paul Tomblin    schedule 23.02.2009
comment
blogs.msdn.com/b/oldnewthing/archive/ 2005/06/07 / 426294.aspx   -  person Hello71    schedule 09.02.2011
comment
@ Hello71: Хороший пост в блоге, но в нем обсуждается Microsoft Windows. Я не понимаю, как это применимо к этому вопросу, за исключением, может быть, наиболее общих принципов операционной системы.   -  person Robert Harvey    schedule 11.02.2011
comment
похоже на меня: - stackoverflow.com/questions/13452587/   -  person Pradeep Goswami    schedule 18.12.2015
comment
Для тех, кто не знает, липкий бит не имеет никакого отношения к управлению памятью и никогда не имеет. Это не относится и к файлам.   -  person wheredidthatnamecomefrom    schedule 10.11.2016


Ответы (7)


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

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

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

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

person Thomas Kammeyer    schedule 23.02.2009
comment
@sanity ты пробовал это? Как это сработало для вас? Я подумывал сделать что-то подобное. - person Bill K; 27.10.2010
comment
@Mat кажется правым ... Хорошо ... как насчет того, чтобы написать что-то для вызова через JNI, которое вызывает mlockall? Хотя это начинает казаться довольно хакерским ... - person Thomas Kammeyer; 25.06.2012
comment
Если вы не хотите возиться с пользовательскими библиотеками JNI, вы, вероятно, можете использовать JNA для прямого вызова mlockall. - person plugwash; 03.11.2015
comment
Расширение, хитрый прием: если процесс не делает этот mlockall() вызов за вас, вы можете помочь ему с помощью gdb, позволяя ему вызывать это ради вас. :-) - person peterh; 01.02.2016

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

https://unix.stackexchange.com/questions/10214/per-process-swapiness-for-linux#10227

person Matthew Buckett    schedule 10.09.2012

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

person jpalecek    schedule 23.02.2009
comment
Я бы был осторожен, какая часть общей системной памяти заблокирована. Я подозреваю, что вы могли бы вывести систему из строя, если не будете осторожны. - person Dana the Sane; 23.02.2009

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

person SumoRunner    schedule 23.02.2009
comment
если я не ошибаюсь, это повлияет только на процессорное время, предоставленное процессу, а не на его тенденцию к использованию основной памяти. - person intuited; 23.05.2010
comment
@intuited: я полагаю, он имеет в виду, что подсистема виртуальной машины также будет смотреть на значение nice, чтобы решить, насколько важен процесс, а не менять его местами. Звучит правдоподобно; Однако я не знаю, действительно ли Linux это делает. - person sleske; 09.02.2011
comment
ionice также может быть здесь полезен - person fread2281; 03.06.2015

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

mysqld включает код для использования OS / системного вызова memlock. В Linux, начиная с версии 2.6.9, этот системный вызов будет работать для некорневых процессов, которые имеют возможность 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, отмечаю следующее:

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

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

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

person dwc    schedule 23.02.2009
comment
Если бы это было связано с криптографией, было бы вполне разумно захотеть остаться в памяти. gnome-keyring, например, делает несколько шагов, чтобы не допустить подкачки важных частей самого себя. (Помимо этого, разумные наблюдения.) - person Paul Fisher; 23.02.2009
comment
Хорошее замечание, Пол. Я считаю, что это можно назвать необычным обстоятельством. - person dwc; 23.02.2009
comment
Это обычное дело в индустрии банковских и платежных карт со всеми строгими требованиями криптографии. - person Aleksander Adamowski; 24.03.2010
comment
См. Следующий совет (рекомендация MEM06-C - Убедитесь, что конфиденциальные данные не записываются на диск) от CERT, который применяется к программам C в POSIX и Windows: securecoding.cert.org/confluence/display/seccode/ Это довольно стандартные вещи, когда требуется безопасное кодирование. Аналогичные вещи нужны и для Java. - person Aleksander Adamowski; 24.03.2010
comment
Кстати, шифрование пространства подкачки решило бы проблему, но оно по-прежнему не помешало бы привилегированному пользователю системы читать конфиденциальные данные с криптоблочного устройства, которое поддерживает пространство подкачки - возможно, даже спустя долгое время после завершения исходной программы (до тех пор, пока конкретная область подкачки не получит перезаписаны). - person Aleksander Adamowski; 24.03.2010
comment
А как насчет процессов, связанных с пользовательским интерфейсом, которые не используют много памяти? Например, панели диспетчера рабочего стола, что-то в этом роде? элементы пользовательского интерфейса должны быть готовы к работе в любое время или, по крайней мере, более готовыми, чем вещи, которые в основном представляют собой пакетную обработку. В идеале приложения должны быть построены так, чтобы их интерфейс имел более высокий приоритет реальной памяти, чем их внутренности, чтобы EG по-прежнему мог сканировать меню, пока приложение было занято чем-то. Некоторые приложения действительно работают таким образом, но для этого требуется многопоточность. но приложениям, которые являются просто программами запуска и т. д., следует дать более высокую степень закрепления памяти. - person intuited; 23.05.2010
comment
Java, вероятно, следует закодировать таким образом, чтобы область данных никогда не менялась местами - java слишком вероятно переупорядочит все свои данные, что может привести к серьезным сбоям. Однако хранение всей JVM и библиотек в памяти может быть излишним. - person Bill K; 27.10.2010
comment
Это довольно старый ответ, но я должен сказать, что вы обычно делаете это неправильно, потому что кто-то умнее сказал, что это не является уважительной причиной. Я хочу, чтобы мой процесс не менялся местами, и у меня есть 32 ГБ памяти - поэтому меня не волнует, что думали разработчики ядра, когда они разрабатывали свою систему, я не хочу, чтобы мой процесс менялся местами - конец. И я действительно хочу, чтобы мой своп был там, хотя у меня много ресурсов. Я бы сказал, что такие ответы, как ваш, не вносят ничего нового в дискуссию, и я бы предпочел не видеть таких ответов, когда буду искать решение своей проблемы. - person Greg0ry; 18.03.2016

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

person Martin Beckett    schedule 23.02.2009