Я обнаружил, что pidstat
это будет хорошим инструментом для мониторинга процессов. Я хочу рассчитать среднее использование памяти для определенного процесса. Вот пример выходных данных:
02:34:36 PM PID minflt/s majflt/s VSZ RSS %MEM Command
02:34:37 PM 7276 2.00 0.00 349212 210176 7.14 scalpel
(Это часть вывода из pidstat -r -p 7276
.)
Должен ли я использовать информацию о резидентном наборе (RSS) или виртуальном размере (VSZ) для расчета среднего потребления памяти? Я прочитал кое-что в Википедии и на форумах, но я не уверен, что полностью понимаю различия. Кроме того, кажется, что ни один из них не является надежным. Итак, как я могу контролировать процесс, чтобы получить его использование памяти?
Любая помощь по этому вопросу будет полезна.
Ответы:
RSS - это количество памяти, которое этот процесс в настоящее время имеет в основной памяти (RAM). VSZ - это количество виртуальной памяти, которое имеет процесс в целом. Это включает в себя все типы памяти, как в оперативной памяти, так и подкачки. Эти числа могут быть искажены, потому что они также включают в себя общие библиотеки и другие типы памяти. У вас может быть пятьсот экземпляров
bash
, и общий размер их памяти не будет суммой их значений RSS или VSZ.Если вам необходимо получить более подробное представление об объеме памяти процесса, у вас есть несколько вариантов. Вы можете пройти
/proc/$PID/map
и отсеять то, что вам не нравится. Если это общие библиотеки, расчет может быть сложным в зависимости от ваших потребностей (что, я думаю, я помню).Если вас волнует только размер кучи процесса, вы всегда можете просто проанализировать
[heap]
запись вmap
файле. Размер, выделенный ядром для кучи процесса, может отражать или не отражать точное количество байтов, которые процесс запросил для выделения. Есть мелкие детали, внутренности ядра и оптимизации, которые могут скинуть это. В идеальном мире это будет столько, сколько нужно вашему процессу, округленное до ближайшего кратного размера системной страницы (getconf PAGESIZE
скажет вам, что это такое - на ПК это, вероятно, 4096 байт).Если вы хотите увидеть, сколько памяти выделил процесс , одним из лучших способов является отказ от метрик на стороне ядра. Вместо этого вы используете
LD_PRELOAD
механизм выделения (удаления) памяти кучи библиотеки C с помощью этого механизма. Лично я немного ругаюсь,valgrind
чтобы получить информацию об этом. (Обратите внимание, что применение инструментов потребует перезапуска процесса.)Обратите внимание: поскольку вы также можете тестировать время выполнения, это
valgrind
сделает ваши программы немного медленнее (но, вероятно, в пределах ваших допусков).источник
/proc/$PID/maps
опечатка или разница в дистрибутивах?Минимальный исполняемый пример
Чтобы это имело смысл, вы должны понимать основы подкачки: https://stackoverflow.com/questions/18431261/how-does-x86-paging-work и, в частности, что ОС может выделять виртуальную память через таблицы страниц / ведение внутренней памяти (виртуальная память VSZ) до того, как у нее фактически будет резервное хранилище в ОЗУ или на диске (резидентная память RSS).
Теперь, чтобы увидеть это в действии, давайте создадим программу, которая:
mmap
main.c
GitHub вверх по течению .
Скомпилируйте и запустите:
где:
echo 1 | sudo tee /proc/sys/vm/overcommit_memory
: требуется для Linux, чтобы мы могли сделать вызов mmap больше физической ОЗУ: https://stackoverflow.com/questions/2798330/maximum-memory-which-malloc-can-allocate/57687432#57687432Выход программы:
Статус выхода:
что по правилу 128 + номер сигнала означает, что мы получили номер сигнала
9
, которыйman 7 signal
говорит , что это SIGKILL , который посылает убийца нехватки памяти Linux .Выходная интерпретация:
printf '0x%X\n' 0x40009A4 KiB ~= 64GiB
(ps
значения в КиБ) после mmap.extra_memory_committed 0
, что означает, что мы еще не коснулись ни одной страницы. RSS - это небольшой файл,1648 KiB
который был выделен для обычного запуска программы, такого как текстовая область, глобальные переменные и т. Д.8388608 KiB == 8GiB
стоимости страниц. В результате RSS увеличился ровно на 8GIB до8390256 KiB == 8388608 KiB + 1648 KiB
См. Также: Требуется объяснение размера резидентного набора / виртуального размера
Журналы убийцы ООМ
Наши
dmesg
команды показали журналы убийцы OOM.Точная интерпретация этих вопросов была задана по адресу:
Самая первая строка журнала была:
Итак, мы видим, что интересно, что это был демон MongoDB, который всегда запускался в моем ноутбуке на фоне, который первым вызвал убийцу OOM, предположительно, когда бедняга пытался выделить немного памяти.
Однако убийца ООМ не обязательно убивает того, кто его разбудил.
После вызова ядро печатает таблицу или процессы, включая
oom_score
:и далее мы видим, что наш маленький на
main.out
самом деле был убит при предыдущем вызове:В этом журнале упоминается,
score 865
какой процесс имел, предположительно, самый высокий (наихудший) показатель убийцы OOM, как упомянуто в: Как убийца OOM решает, какой процесс убить первым?Также интересно то, что все, по-видимому, произошло так быстро, что до того, как освободившаяся память была учтена, процесс
oom
снова пробудилсяDeadlineMonitor
:и на этот раз это убило какой-то процесс Chromium, который обычно является моим компьютером обычным занятием памяти:
Протестировано в Ubuntu 19.04, ядро Linux 5.0.0.
источник