Пиковое использование памяти процессом linux / unix


376

Есть ли инструмент, который будет запускать командную строку и сообщать о пиковом общем объеме использования ОЗУ?

Я представляю себе нечто аналогичное / usr / bin / time

Ответы:


28

Вот одна строка, которая не требует каких-либо внешних сценариев или утилит и не требует, чтобы вы запускали процесс с помощью другой программы, такой как Valgrind или time, поэтому вы можете использовать ее для любого процесса, который уже запущен:

grep VmPeak /proc/$PID/status

(замените $PIDна PID интересующего вас процесса)


4
Что если я не знаю PID? Например, в случае, когда программа запускается небольшое количество времени (<
1сек

4
«VmHWM: Пиковый размер резидентного набора» может быть более пригодным для измерения использования оперативной памяти (вместо VmPeak, который также включает в себя множество других вещей).
JFS

@jfs это действительно зависит от того, что ты хочешь узнать. IIRC VmPeak - это максимальное суммарное использование памяти, включая виртуальную, в то время как VmHWM - пиковое использование ОЗУ. Поэтому, если вы хотите узнать общий объем памяти, запрошенный вашей программой, используйте VmPeak; если вы хотите узнать, сколько вашей оперативной памяти он когда-либо использовал в данный момент, используйте VmHWM.
erobertc

1
@diralik Если вы проверяете программу, написанную самостоятельно, вы можете вставить строку кода, чтобы просмотреть файл "/ proc / self / status".
Филленд

405

[ Редактировать : Работает в Ubuntu 14.04: /usr/bin/time -v command Убедитесь, что вы указали полный путь.]

Похоже /usr/bin/time, дает вам эту информацию, если вы передаете -v(это на Ubuntu 8.10). Смотрите, например, Maximum resident set sizeниже:

$ / usr / bin / time -v ls /
....
        Время выполнения команды: "ls /"
        Пользовательское время (секунды): 0,00
        Системное время (секунды): 0,01
        Процент CPU, который получил это задание: 250%
        Истекшее время (настенные часы) (ч: мм: сс или м: сс): 0: 00.00
        Средний общий размер текста (в килобайтах): 0
        Средний размер общего ресурса (в килобайтах): 0
        Средний размер стека (кбайт): 0
        Средний общий размер (кбайт): 0
        Максимальный размер резидентного набора (в килобайтах): 0
        Средний размер резидентного набора (в килобайтах): 0
        Основные (требующие ввода / вывода) ошибки страницы: 0
        Незначительные (исправление кадра) ошибки страницы: 315
        Добровольные переключения контекста: 2
        Непроизвольные переключения контекста: 0
        Свопы: 0
        Входы файловой системы: 0
        Выходы файловой системы: 0
        Отправлено сообщений: 0
        Получено сообщений: 0
        Доставлено сигналов: 0
        Размер страницы (в байтах): 4096
        Статус выхода: 0

4
Вероятно, он всегда возвращает 0, потому что ls мало что делает. Попробуйте более интенсивную загрузку процессора.
Джон Эриксон

17
Со страницы man: большая часть информации, отображаемой временем, получена из системного вызова wait3 (2). Числа так же хороши, как и те, что возвращены wait3 (2). В системах, где нет вызова wait3 (2), который возвращает информацию о состоянии, вместо этого используется системный вызов times (2). Тем не менее, он предоставляет гораздо меньше информации, чем wait3 (2), поэтому в этих системах время сообщает, что большинство ресурсов равно нулю.
Лотар

79
«bash: -v: команда не найдена» означает, что bash перехватывает время, чтобы использовать свое собственное. /bin/time -vрешает это.
ГКБ

3
Стоит сделать быструю проверку, чтобы убедиться, что вывод имеет смысл. У Gnu time есть ошибка, из-за которой она в 4 раза сообщает о фактическом использовании памяти: stackoverflow.com/questions/10035232/…
Ян

24
@skalee Попробуй time -lна MacOS, выдаст похожий вывод.
Volker Stolz

96

(Это уже отвеченный старый вопрос .. но только для записи :)

Я был вдохновлен сценарием Янга и придумал этот маленький инструмент, названный memusg . Я просто увеличил частоту дискретизации до 0,1, чтобы справиться с очень короткими жизненными процессами. Вместо того, чтобы отслеживать отдельный процесс, я сделал так, чтобы он измерял rss сумму группы процессов. (Да, я пишу много отдельных программ, которые работают вместе). В настоящее время он работает на Mac OS X и Linux. Использование должно было быть аналогичным использованию time:

memusg ls -alR /> / dev / null

Это только показывает пик на данный момент, но меня интересуют небольшие расширения для записи другой (грубой) статистики.

Хорошо иметь такой простой инструмент, чтобы просто посмотреть, прежде чем мы начнем серьезное профилирование.


1
все, что все еще использует PS и только хорошо, чтобы определить наблюдаемую верхнюю память. не реальная верхняя память. Вы всегда можете пропустить что-то между одним интервалом и другим.
ГКБ

6
Каковы единицы для вывода скрипта memusg? Б? Килобайт?
Даниэль Стендж

1
@DanielStandage: вероятно, в килобайтах. Он просто просматривает значения, показанные ps -o rss=где rss - это реальный размер памяти (резидентный набор) процесса (в 1024 байтных единицах) из моей справочной страницы BSD.
нет

3
@gcb Ну и что, это то, что вы получаете, когда измеряете образцы.
Фолькер Штольц

2
Ссылка на memusg, приведенная в ответе, кажется, не работает. В любом случае, / usr / bin / time делает это очень хорошо.
Том Корнебиз,

65

Valgrind один вкладыш:

valgrind --tool=massif --pages-as-heap=yes --massif-out-file=massif.out ./test.sh; grep mem_heap_B massif.out | sed -e 's/mem_heap_B=\(.*\)/\1/' | sort -g | tail -n 1

Обратите внимание на использование --pages-as-heap для измерения всей памяти в процессе. Более подробная информация здесь: http://valgrind.org/docs/manual/ms-manual.html


14
time, Я покидаю тебя.
jbeard4

1
Удобный скрипт, но мне нужна сортировка -g в моей системе Slackware (полагаю, вы ищете самое высокое значение).
Ник Коулман

3
+1 за valgrind --massif. Вы также можете использовать ms_printинструмент, который поставляется с ним для удобного вывода (включая графики использования ASCII с течением времени)
Eli Bendersky

7
Массив имеет гораздо более высокие накладные расходы, чем timeхотя бы, занимая как минимум в 10 раз больше времени на подобную команду ls.
Тимоти Гу

8
Это действительно слишком массивно. Этот ответ должен упомянуть замедление. Команда, которую я хочу измерить, обычно занимает 35 секунд. Я выполнил эту команду valgrind, чтобы измерить ее более получаса назад, и она все еще не завершена ...
Унаги

35

В Linux:

Используйте /usr/bin/time -v <program> <args>и ищите « Максимальный размер резидентного набора ».

(Не путать со timeвстроенной командой Bash ! Поэтому используйте полный путь , /usr/bin/time)

Например:

> /usr/bin/time -v ./myapp
        User time (seconds): 0.00
        . . .
        Maximum resident set size (kbytes): 2792
        . . .

На BSD, MacOS:

Используйте /usr/bin/time -l <program> <args>, ища « максимальный размер резидентного набора »:

>/usr/bin/time -l ./myapp
        0.01 real         0.00 user         0.00 sys
      1440  maximum resident set size
      . . .

sudo apt-get install time
Рольф

2
Разве это основание уже не покрыто ответом, добавленным двумя годами ранее ?
Чарльз Даффи

34

Возможно (GNU) время (1) уже делает то, что вы хотите. Например:

$ /usr/bin/time -f "%P %M" command
43% 821248

Но другие инструменты профилирования могут дать более точные результаты в зависимости от того, что вы ищете.


Я, кажется, всегда получаю нули с этим, даже для больших команд
jes5199

Я получаю переменные результаты, например, 400% 0 и 0% 0 в одной и той же программе. Может быть, если быть точным, нужно запускать на более длительные периоды времени?
Лиран Ореви

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

2
Это работает по крайней мере на CentOS (и, я уверен, также на RHEL) системах. % P дает несвязанную статистику (% CPU), которая зависит от планировщика и, таким образом, является довольно изменчивой.
Blaisorblade

2
@Deleteman: timeвстроенная команда при использовании csh. Если вы используете точный путь, это позволит вам выполнить внешнюю команду. Насколько я знаю, только версия GNU поддерживает опцию формата.
Джон Эриксон

18

/ usr / bin / time, возможно, делает то, что вы хотите, на самом деле. Что-то вроде.

 / usr / bin / time --format = '(% Xtext +% Ddata% Mmax)'

Смотрите время (1) для деталей ...


1
Я, кажется, всегда получаю нули с этим, даже для больших команд
jes5199

jes5199, Лиран, просматривая вышеупомянутые комментарии, кажется, что время (1) может быть нарушено для отчетов о памяти для некоторых linux ...
simon

В Ubuntu 16.04 текст и данные равны нулю, но max не равен нулю и дает значимое значение. Я рада этому.
Стефан Гурихон

Я надеюсь, что Mmax там означает то, что мы хотим, чтобы это означало .... страница руководства немного кратко об этом
matanster

17

На MacOS Sierra используйте:

/usr/bin/time -l commandToMeasure

Вы можете использовать, grepчтобы взять то, что вы хотите, может быть.


5
Эта! Я буквально потратил час, пытаясь получить Instruments.app и dtrace, чтобы дать мне профиль памяти с включенной целостностью системы (не могу ее отключить), в то время как все, что мне было нужно, это просто эта простая команда. Небольшое примечание, которое вы можете использовать command time -lвместо /usr/bin/time -lкоторого, заставит вашу оболочку фактически вызывать двоичный файл, вызываемый timeвместо встроенной функции. (Да, commandне заполнитель, command timeотличается от просто time.)
Якуб Арнольд

16

Если процесс выполняется в течение как минимум пары секунд, вы можете использовать следующий скрипт bash, который запустит заданную командную строку, а затем напечатает для stderr пикового RSS (замените rssлюбой другой интересующий вас атрибут). Это несколько легкий, и он работает для меня с psвключенным в Ubuntu 9.04 (что я не могу сказать time).

#!/usr/bin/env bash
"$@" & # Run the given command line in the background.
pid=$! peak=0
while true; do
  sleep 1
  sample="$(ps -o rss= $pid 2> /dev/null)" || break
  let peak='sample > peak ? sample : peak'
done
echo "Peak: $peak" 1>&2

1
Основным недостатком этого метода является то, что если процесс выделяет много памяти на короткий период (например, ближе к концу), это может быть не обнаружено. Сокращение времени сна может помочь немного.
vinc17


8

Что ж, если вы действительно хотите показать пик памяти и более подробную статистику, я рекомендую использовать такой профилировщик, как valgrind . Хороший интерфейс Valgrind - это Alleyoop .



5

Вот (на основе других ответов) очень простой скрипт, который отслеживает уже запущенный процесс. Вы просто запускаете его с pid процесса, который хотите видеть в качестве аргумента:

#!/usr/bin/env bash

pid=$1

while ps $pid >/dev/null
do
    ps -o vsz= ${pid}
    sleep 1
done | sort -n | tail -n1

Пример использования:

max_mem_usage.sh 23423


1

Heaptrack - это инструмент KDE с графическим интерфейсом и текстовым интерфейсом. Я нахожу более подходящим, чем valgrind, понять использование памяти процессом, поскольку он предоставляет больше деталей и флеймграфов. Это также быстрее, потому что он меньше проверяет этот valgrind. И это дает вам пиковое использование памяти.

В любом случае, отслеживание rss и vss вводит в заблуждение, потому что страницы могут быть общими, вот почему memusg. Что вы действительно должны сделать, это отслеживать сумму Pssв /proc/[pid]/smapsили использования pmap. Системный монитор GNOME раньше делал это, но это было слишком дорого.


1

Переизобретая колесо, с помощью скрипта bash, сделанного вручную. Быстро и чисто.

Мой пример использования: я хотел отслеживать машину linux, у которой меньше оперативной памяти, и хотел сделать снимок использования каждого контейнера, когда он работает в условиях интенсивной работы.

#!/usr/bin/env bash

threshold=$1

echo "$(date '+%Y-%m-%d %H:%M:%S'): Running free memory monitor with threshold $threshold%.."

while(true)
    freePercent=`free -m | grep Mem: | awk '{print ($7/$2)*100}'`    
  do

  if (( $(awk 'BEGIN {print ("'$freePercent'" < "'$threshold'")}') ))
  then
       echo "$(date '+%Y-%m-%d %H:%M:%S'): Free memory $freePercent% is less than $threshold%"
       free -m
       docker stats --no-stream
       sleep 60  
       echo ""  
  else
       echo "$(date '+%Y-%m-%d %H:%M:%S'): Sufficient free memory available: $freePercent%"
  fi
  sleep 30

done

Пример вывода:

2017-10-12 13:29:33: Запуск монитора свободной памяти с порогом 30% ..

2017-10-12 13:29:33: Достаточно свободной памяти: 69,4567%

2017-10-12 13:30:03: Доступно достаточно свободной памяти: 69,4567%

2017-10-12 16:47:02: Свободная память 18,9387% меньше 30%

ваш собственный вывод команды


1

В macOS вы можете использовать DTrace. Приложение "Инструменты" - хороший графический интерфейс для этого, оно поставляется с XCode afaik.


0

'htop' - лучшая команда для определения того, какой процесс использует сколько оперативной памяти .....

для получения более подробной информации http://manpages.ubuntu.com/manpages/precise/man1/htop.1.html


3
htop не перечисляет использование ПИК. Только ТЕКУЩЕЕ использование. (Если вы не знаете что-то, чего я не знаю. Как я вчера выглядел в htop для этого точного сценария.)
Katastic Voyage

-2

Пожалуйста, обязательно ответьте на вопрос. Предоставьте детали и поделитесь своими исследованиями!

Извините, я здесь впервые и могу только задавать вопросы ...

Используется предложено:

valgrind --tool=massif --pages-as-heap=yes --massif-out-file=massif.out ./test.sh; grep mem_heap_B massif.out | sed -e 's/mem_heap_B=\(.*\)/\1/' | sort -g | tail -n 1

тогда:

grep mem_heap_B massif.out
...
mem_heap_B=1150976
mem_heap_B=1150976
...

это очень отличается от того, что topпоказывает команда в аналогичный момент:

14673 gu27mox   20   0 3280404 468380  19176 R 100.0  2.9   6:08.84 pwanew_3pic_com

Какие единицы измерения от Valgrind?

/usr/bin/time -v ./test.shНикогда не ответили - вы должны непосредственно кормить исполняемый /usr/bin/timeкак:

/usr/bin/time -v  pwanew_3pic_compass_2008florian3_dfunc.static  card_0.100-0.141_31212_resubmit1.dat_1.140_1.180   1.140 1.180 31212


    Command being timed: "pwanew_3pic_compass_2008florian3_dfunc.static card_0.100-0.141_31212_resubmit1.dat_1.140_1.180 1.140 1.180 31212"

    User time (seconds): 1468.44
    System time (seconds): 7.37
    Percent of CPU this job got: 99%
    Elapsed (wall clock) time (h:mm:ss or m:ss): 24:37.14
    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): 574844
    Average resident set size (kbytes): 0
    Major (requiring I/O) page faults: 74
    Minor (reclaiming a frame) page faults: 468880
    Voluntary context switches: 1190
    Involuntary context switches: 20534
    Swaps: 0
    File system inputs: 81128
    File system outputs: 1264
    Socket messages sent: 0
    Socket messages received: 0
    Signals delivered: 0
    Page size (bytes): 4096
    Exit status: 0
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.