LINUX.ORG.RU
решено ФорумAdmin

Ограничение RSS памяти, с учётом SHR

 , ,


0

1

Тестирую код, жрущий много памяти. Память жрётся по 2м направлениям: анонимные аллокации и shared через mmap 17GB файла с MADV_WILLNEED.

Хочу протестировать скорость, как если бы памяти на хосте было 10GB. На машине реально 32GB + 11GB swap.

Беру systemd-run, пробую:

$ systemd-run --user --scope -p MemoryMax=1G -p MemoryHigh=1G -p MemorySwapMax=0 ./memory_hungry_app
...
Killed

Ок, значит какое-то ограничение отрабатывает. Пробую 10G:

$ systemd-run --user --scope -p MemoryMax=10G -p MemoryHigh=10G -p MemorySwapMax=0 env time -v ./memory_hungry_app

...
Maximum resident set size (kbytes): 18529480 (18GB)

Может prlimit?

$ prlimit -m=1073741824 prlimit
...
RSS        max resident set size              SOFT:1073741824 HARD:1073741824 bytes
$ prlimit -m=1073741824 env time -v ./memory_hungry_app
...
 Maximum resident set size (kbytes): 20522316

Т.е. эти утилиты не учитывают SHR в своих ограничениях. А хочется, чтобы системный кеш шаренных страниц этого процесса освобождался до пределов в 10GB.

Прочитанные мануалы:

  • man 5 systemd.resource-control – вроде нет других Memory;
  • man 2 getrlimit – RLIMIT_RSS: This limit has effect only in Linux 2.4.x, x < 30, and there affects only calls to madvise(2) specifying MADV_WILLNEED";

Какую ещё тулзу к cgroups попробовать? Хочется, чтобы без редактирования конфигов и контейнеров.

★★★★★

Последнее исправление: snizovtsev (всего исправлений: 3)

Какие еще процессы используют эти shared страницы? Возможно, лимиты будут работать лучше, если все они будут сидеть в одной группе по памяти. Но вообще надо читать ядерные доки по cgroups, какие там есть лимиты и что они умеют. Тулзы - просто удобная обертка, они не могут сделать ничего принципиально иного, чего нельзя было бы сделать руками из шелла.

annulen ★★★★★
()
Ответ на: комментарий от intelfx

Сначала ответь на вопрос — сами cgroups умеют то, что тебе нужно?

Ок, давайте переформулируем это так. Хотя я думаю сейчас на ebpf можно сделать любые ограничения, поэтому от тулзы тоже многое зависит.

Cgexec с конфигом:

group xxx {
    memory {
        memory.limit_in_bytes = 1073741824;
    }
}

Тоже работает как системд.

snizovtsev ★★★★★
() автор топика

Ещё есть подозрение, что страницы в page cache, которые там уже были на момент запуска процесса, не «переприсваиваются» его цгруппе, когда он к ним первый раз обращается.

Попробуй сбросить страничный кэш и запустить ещё раз.

intelfx ★★★★★
()
Ответ на: комментарий от intelfx

Попробуй сбросить страничный кэш и запустить ещё раз.

Внезапно, сработало! SHR аккуратно балансировал на том уровне, чтобы не превысить 10GB RSS.

Спасибо! Тему закрываю.

snizovtsev ★★★★★
() автор топика
Последнее исправление: snizovtsev (всего исправлений: 2)
Ответ на: комментарий от snizovtsev

Ничего внезапного :) Cgroup memory accounting именно так и работает, вновь загруженные страницы засчитываются той цгруппе, по инициативе которой они были загружены (ну, минус приседания с readahead). Соответственно, страницы, которые уже есть в кэше, далее никак своё владение не меняют (ну разве что только на родительскую цгруппу, когда исходная уничтожается, если я правильно помню).

intelfx ★★★★★
()
Последнее исправление: intelfx (всего исправлений: 1)