Как измерить пиковое использование памяти деревом процессов?

Вопрос или проблема

Под процессным деревом я понимаю процесс и все, что он выполняет любым образом.

Я пробовал /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 помогут вам в мониторинге в реальном времени.

Оцените материал
Добавить комментарий

Капча загружается...