Вопрос или проблема
Под процессным деревом я понимаю процесс и все, что он выполняет любым образом.
Я пробовал /usr/bin/time -v
, но результаты совершенно неверны. Например, запуск npm test
в одном из наших проектов при 14 ГБ свободной оперативной памяти и 8 ГБ свободного свопа приводит к тому, что OOM-убийца начинает убивать мои приложения (чаще всего это браузер и IDE). time
сообщает, что было использовано только 800 МБ, хотя реальное потребление памяти должно было быть очень высоким, более 20 ГБ…
Сначала я бы использовал smem
. Например, вы можете использовать smem -tas uss
, чтобы получить обзор.
-t
… показываетTotals-a
… автоматически настраивает ширину столбцов-s uss
… сортирует результат на основе колонки uss
Чтобы увидеть детали по процессу, лучше всего использовать pmap
. Чтобы получить подробную информацию, вам следует использовать переключатель -X
. Чтобы получить всю информацию, которую предоставляет ядро, можно использовать -XX
, что обычно является избыточным.
Чтобы получить мониторинг с обновлением каждые 2 секунды для pid 3120:
watch -n 2 pmap -X 3120
Редактировать: чтобы на самом деле получить пик Вышеуказанное помогает в мониторинге, но не показывает фактический пик. Ушло из головы.
Я бы лично использовал valgrind
с инструментом massif
.
valgrind --tool=massif --pages-as-heap=yes --massif-out-file=evolution_massif.out evolution; grep mem_heap_B evolution_massif.out | sed -e 's/mem_heap_B=\(.*\)/\1/' | sort -g | tail -n 1
Объяснение:
--page-as-heap=yes
… говорит massif, что он должен учитывать всю память вместо только кучи--massif-out-file
… выходной файл для инструмента massif- evolution … приложение, которое должно быть смонтировано
Следующая часть предназначена для того, чтобы узнать максимальное зафиксированное значение.
grep
ищет вхождения mem_heap_B. sed -e
убирает строку mem_heap_B
, так что мы получаем только числовой результат. Затем мы сортируем его через sort -g
, который является общим числовым сортировочным и берем самое большое число с помощью tail -n 1
, которое возвращает первую строку отсортированных чисел.
После завершения приложения valgrind
выведет одно число, которое является пиком памяти в [B]айтах.
Проверка журнала пиков памяти
Чтобы отобразить выходной файл evolution_massif.out, вы можете использовать инструмент постобработки ms_print
для Massif.
Это просто:
ms_print evolution_massif.out
Вывод должен выглядеть примерно так (это первая страница вывода), где вы можете увидеть, какой снимок был пиковым – 10 (пик):
--------------------------------------------------------------------------------
Команда: evolution
Аргументы Massif: --pages-as-heap=yes --massif-out-file=massif.out
Аргументы ms_print: massif.out
--------------------------------------------------------------------------------
ГБ
10.09^ #
| #
| #
| #
| #
| #
| # @:::::@::::::::::::::::@@:::::@:::::@::::::@::::@:::::@::
| # @:::::@: :::::::: :::: @@:::::@:::::@::::::@::::@:::::@::
| #::::::@:::::@: :::::::: :::: @@:::::@:::::@::::::@::::@:::::@::
| #::::: @:::::@: :::::::: :::: @@:::::@:::::@::::::@::::@:::::@::
| #::::: @:::::@: :::::::: :::: @@:::::@:::::@::::::@::::@:::::@::
| #::::: @:::::@: :::::::: :::: @@:::::@:::::@::::::@::::@:::::@::
| #::::: @:::::@: :::::::: :::: @@:::::@:::::@::::::@::::@:::::@::
| #::::: @:::::@: :::::::: :::: @@:::::@:::::@::::::@::::@:::::@::
| #::::: @:::::@: :::::::: :::: @@:::::@:::::@::::::@::::@:::::@::
| #::::: @:::::@: :::::::: :::: @@:::::@:::::@::::::@::::@:::::@::
| #::::: @:::::@: :::::::: :::: @@:::::@:::::@::::::@::::@:::::@::
| @ #::::: @:::::@: :::::::: :::: @@:::::@:::::@::::::@::::@:::::@::
| :::@::#::::: @:::::@: :::::::: :::: @@:::::@:::::@::::::@::::@:::::@::
0 +----------------------------------------------------------------------->Ги
0 8.927
Количество снимков: 97
Подробные снимки: [7, 10 (пик), 17, 24, 43, 44, 50, 60, 70, 80, 90]
--------------------------------------------------------------------------------
n время(i) всего(B) полезная-куча(B) дополнительная-куча(B) стеки(B)
--------------------------------------------------------------------------------
0 0 16,384 16,384 0 0
1 149,772,704 393,547,776 393,547,776 0 0
2 243,902,287 398,592,800 398,592,800 0 0
3 396,613,298 558,157,704 558,157,704 0 0
4 504,752,503 638,138,760 638,138,760 0 0
5 604,812,936 639,894,808 639,894,808 0 0
...
Редактировать, чтобы добавить всех потомков:
Чтобы добавить всех потомков (детей), вы можете добавить опцию --trace-children=yes
к команде valgrind
.
Вы можете запустить ваш проект npm как службу systemd. Это покажет вам пик использования памяти процесса и всех его потомков следующим образом:
$ service npm status
● npm.service - npm демон
Загружено: загружено (/etc/systemd/system/npm.service; включено; предустановка: включено)
Активно: активно (работает) с Вт 2024-10-08 17:57:36 CEST; 1 день 13ч назад
Процесс: 229628 ExecStartPost=process (код=вышел, статус=0/УСПЕХ)
Основной PID: 229627 (npm)
Задания: 23 (ограничение: 18998)
Память: 445.7М (пик: 2.8Г)
CPU: 20мин 9.660с
Ответ или решение
Измерение пикового потребления памяти процесса и его дочерних процессов (дерева процессов) может быть выполнено с использованием различных инструментов и методов. Вот несколько подходов, которые вы можете рассмотреть.
1. Использование smem
Вы можете начать с команды smem
, которая предоставляет информацию о распределении использования памяти между процессами. Например, команда:
smem -tas uss
где:
-t
— показывает общие значения,-a
— автонастраивает ширину столбцов,-s uss
— сортирует результаты по колонке USS (Unique Set Size).
Это даст вам обзор потребления памяти всеми процессами, однако для более детальной информации о конкретных процессах может потребоваться другой инструмент.
2. Использование pmap
Для получения детализированной информации по конкретному процессу можно использовать команду pmap
. Например, чтобы отслеживать выделение памяти процесса с PID 3120:
watch -n 2 pmap -X 3120
Опция -X
предоставляет подробные данные о выделении памяти, а -XX
предоставляет всю доступную информацию от ядра, однако это обычно избыточно.
3. Измерение пикового потребления с помощью Valgrind
Для измерения пикового потребления памяти вы можете использовать инструмент Valgrind
, а именно его модуль massif
. Запустите ваше приложение с помощью Valgrind
следующим образом:
valgrind --tool=massif --pages-as-heap=yes --massif-out-file=evolution_massif.out evolution
Этот подход:
--pages-as-heap=yes
говоритmassif
, что следует учитывать всю память, а не только кучу,--massif-out-file
задает файл для вывода данных.
После завершения работы приложения вы можете получить максимальное потребление памяти, выполнив:
grep mem_heap_B evolution_massif.out | sed -e 's/mem_heap_B=\(.*\)/\1/' | sort -g | tail -n 1
Этот набор команд ищет значения памяти в выходном файле, извлекает числовые данные, сортирует их и выводит максимальное значение.
4. Просмотр данных с помощью ms_print
Чтобы выводить результаты работы massif
, используйте следующую команду:
ms_print evolution_massif.out
Эта команда формирует понятный отчет, включая информацию о пике потребления памяти.
5. Запуск в качестве службы systemd
Если ваше приложение может быть запущено как служба systemd
, вы можете использовать следующую команду для получения информации о пиковом потреблении памяти:
service npm status
Это позволит вам увидеть пиковое потребление памяти для процесса и всех его дочерних процессов.
Заключение
Для правильного измерения пикового потребления памяти вашего процессного дерева рекомендуется комбинировать указанные методы, чтобы получить полную картину использования памяти. При использовании Valgrind
и massif
вы сможете получить наиболее точные показатели, в то время как smem
и pmap
помогут вам в мониторинге в реальном времени.