Измерение использования оперативной памяти программы

46

time это блестящая команда, если вы хотите выяснить, сколько процессорного времени занимает данная команда.

Я ищу что-то подобное, что может измерить максимальное использование оперативной памяти программы и любых детей. Предпочтительно следует различать выделенную память, которая использовалась и не использовалась. Может быть, это может даже дать среднее использование памяти (так что использование памяти вы должны ожидать при работе в течение длительного времени).

Итак, я хотел бы сделать:

rammeassure my_program my_args

и получить вывод, похожий на:

Max memory allocated: 10233303 Bytes
Max memory used: 7233303 Bytes
Median memory allocation: 5233303 Bytes

Я посмотрел на memusg https://gist.github.com/526585/590293d6527c91e48fcb08edb8de9fd6c88a6d82, но я считаю это несколько взломом.

Оле Танге
источник

Ответы:

24

Вы можете использовать tstime для измерения использования высокопроизводительной памяти (RSS и виртуальной) процесса.

Например:

$ tstime date       
Tue Aug 16 21:35:02 CEST 2011

Exit status: 0

pid: 31169 (date) started: Tue Aug 16 21:35:02 2011
        real   0.017 s, user   0.000 s, sys   0.000s
        rss      888 kb, vm     9764 kb

Он также поддерживает более легкий для анализа режим вывода ( -t).

maxschlepzig
источник
Мне это нравится. Это даже сделало Правильную вещь с./tstime -t bash -c 'perl -e "\$a=\"x\"x100000000;\$b=\$a.\$a;\$b=\"\";\$a=\"\";sleep 10;"'
Оле Тэндж
3
«Использование ОЗУ процессом» не является четко определенным значением: если запущено несколько экземпляров одной и той же программы, они совместно используют исполняемый файл. Большинство программ совместно используют glibc(и другие разные библиотеки, они для чего-то называются «общими»). Многие демоны загружают конфигурацию в память и потомки fork (2), которые затем делятся данными конфигурации. Затем есть данные в буферах readahead / writebehind, управляемых ядром. Кроме того, существуют сервисы, которые представляют собой стадию слабо связанных процессов (представьте себе среду вашего рабочего стола, все ее апплеты и фоновые компоненты).
vonbrand
@ vonbrand, как ядро ​​Linux вычисляет значения RSS / VSS, четко определено.
maxschlepzig
@maxschlepzig, он вполне может вычислить некоторые случайные значения, но это не значит, что они означают то, что, по вашему мнению, они имеют в виду: резидентный набор - это просто страницы в адресном пространстве процесса, которые в данный момент находятся в памяти. Это не «память, используемая этим процессом», она включает в себя все, чем она делится.
vonbrand
@vonbrand В большинстве случаев при измерении использования памяти процессом нужно измерять нераспределенные анонимные страницы, что должно быть очень предсказуемым при одинаковом вводе.
Владимир Пантелеев
28

timeявляется встроенным в вашей оболочке. Если вам нравится, timeно нужна дополнительная информация, попробуйте GNU timeв режиме verbose ( -v):

/usr/bin/time -v sleep 5               
    Command being timed: "sleep 5"
    User time (seconds): 0.00
    System time (seconds): 0.00
    Percent of CPU this job got: 0%
    Elapsed (wall clock) time (h:mm:ss or m:ss): 0:05.00
    Average shared text size (kbytes): 0
    Average unshared data size (kbytes): 0
    Average stack size (kbytes): 0
    Average total size (kbytes): 0
    Maximum resident set size (kbytes): 2144
    Average resident set size (kbytes): 0
    Major (requiring I/O) page faults: 0
    Minor (reclaiming a frame) page faults: 179
    Voluntary context switches: 2
    Involuntary context switches: 1
    Swaps: 0
    File system inputs: 0
    File system outputs: 0
    Socket messages sent: 0
    Socket messages received: 0
    Signals delivered: 0
    Page size (bytes): 4096
    Exit status: 0

Найдите пакет «time» или «gnutime» в вашем менеджере пакетов.

Руфо Эль Магуфо
источник
3
Обратите внимание, что некоторая информация, сообщаемая временем GNU, может быть неточной. Например, в Ubuntu 10.04: страница руководства гласит: «Числа такие же, как и те, которые были возвращены wait3 (2)». Т.е. wait3заполняет структуру, которая описана в getrusage(2): «Не все поля имеют смысл в Linux. [..].
maxschlepzig
4
Например, в тестовой программе, которая точно выделяет 10 МБ (и касается каждой страницы) - время GNU сообщает maxRSS 42608 КиБ - и tstimeсообщает 10652 КиБ. Снова под Ubuntu 10.04.
maxschlepzig
Я бы любил, если бы это было так просто. На моей машине Ubuntu я пробовал: /usr/bin/time -v perl -e '$a="x"x100000000;$b=$a.$a;sleep 10;'. Топ говорит, что это занимает около 570 МБ, а время говорит о 2,3 ГБ. На практике это число не пригодно для меня.
Оле Танге
Коэффициент 4 фиксируется в GNU time 1.7 и, таким образом, работает как ожидалось.
Оле Танге
Важное примечание: «Максимальный размер резидентного набора» работает только с Linux 2.6.32.
Ян Худек
17

Может быть, излишним, но я только что обнаружил, что valgrindесть хороший инструмент под названием massif. Я проверил это на xterm:

valgrind --trace-children=yes --tool=massif xterm
ms_print massif.out.* | less

И вы получите хороший график использования памяти:

    MB
4.230^                     #                    :::::::  :::      @@:     ::: 
     |   @                 #:::@::@@:::::@::::::: :: : ::: :::::::@ ::::::: ::
     |   @               ::#:: @: @ ::: :@: :: :: :: : ::: ::: : :@ :: : :: ::
     |   @::::@@:::::::::: #:: @: @ ::: :@: :: :: :: : ::: ::: : :@ :: : :: ::
     |   @::: @ :: ::: : : #:: @: @ ::: :@: :: :: :: : ::: ::: : :@ :: : :: ::
     |   @::: @ :: ::: : : #:: @: @ ::: :@: :: :: :: : ::: ::: : :@ :: : :: ::
     |   @::: @ :: ::: : : #:: @: @ ::: :@: :: :: :: : ::: ::: : :@ :: : :: ::
     |   @::: @ :: ::: : : #:: @: @ ::: :@: :: :: :: : ::: ::: : :@ :: : :: ::
     |   @::: @ :: ::: : : #:: @: @ ::: :@: :: :: :: : ::: ::: : :@ :: : :: ::
     |   @::: @ :: ::: : : #:: @: @ ::: :@: :: :: :: : ::: ::: : :@ :: : :: ::
   0 +----------------------------------------------------------------------->Mi
     0                                                                   292.4

наряду со слишком подробной информацией об использовании памяти. Подробности в руководстве Valgrind .

Программы будут работать примерно в 20 раз медленнее. Кроме того, я выполнил несколько команд внутри xterm. Их след памяти был учтен, потому --trace-children=yesчто опция есть!

Стефан Хименес
источник
1
20-кратный штраф скорости делает ее непригодной для моей ситуации. В остальном очень симпатичный график!
Оле Танге
1
Похоже, что по крайней мере в используемой мной версии 3.8.1 valgrind логические значения принимаются только в форме «да / нет», а не «правда / ложь». Мой жаловался! :-)
MakisH
6

Несмотря на то, что тема довольно старая, я хочу поделиться другим проектом, появившимся в ядре Linux cgroups.

https://github.com/gsauthof/cgmemtime :

cgmemtime измеряет интенсивное использование памяти RSS + CACHE для процесса и его дочерних процессов.

Чтобы иметь возможность сделать это, он помещает процесс в свою собственную группу.

Например, процесс A выделяет 10 МБ и разветвляет дочерний элемент B, который выделяет 20 МБ, и разветвляет дочерний элемент C, который выделяет 30 МБ. Все три процесса совместно используют временное окно, в котором их выделения приводят к соответствующему использованию памяти RSS (резидентного набора размеров).

Теперь возникает вопрос: сколько памяти фактически используется в результате запуска A?

Ответ: 60 МиБ

cgmemtime - это инструмент для ответа на такие вопросы.

Влад Фролов
источник
3

Похоже, что tstime больше не работает под не-root под Linux> = 3.0. Вот утилита для опроса, которую я написал для решения этой проблемы: https://github.com/jhclark/memusg/blob/master/memusg

jhclark
источник
/usr/bin/time -vдает правильный вывод в новых версиях. В старых версиях вам просто нужно разделить на 4, чтобы получить правильную сумму.
Оле Танге
Однако я не думаю, что time -v поддерживает пиковый размер памяти (только RSS). Кто-нибудь может подтвердить это на последней версии?
jhclark