mp3 tag editor linux




Как измерять фактическое использование памяти приложения или процесса? (20)

Valgrind поражает, если у вас есть время, чтобы запустить его. valgrind --tool=massif - это правильное решение.

Тем не менее, я начинаю запускать более крупные примеры, и использование valgrind больше не практично. Есть ли способ сообщить максимальное использование памяти (размер страницы и общие страницы) программы?

В реальной системе unix работает /usr/bin/time -v . Однако в Linux это не работает.

Этот вопрос подробно рассматривается here .

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

Из статьи блога « Понимание использования памяти в Linux» ps не является точным инструментом для использования для этого намерения.

Почему ps является «неправильным»

В зависимости от того, как вы смотрите на него, ps не сообщает о реальном использовании памяти процессами. То, что это действительно делает, показывает, насколько реальная память будет обрабатываться каждым процессом, если бы это был единственный процесс . Конечно, типичная Linux-машина имеет несколько десятков процессов, работающих в любой момент времени, что означает, что номера VSZ и RSS, сообщенные ps , почти наверняка ошибочны .


В последних версиях linux используйте подсистему smaps . Например, для процесса с PID 1234:

cat /proc/1234/smaps

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


Если ваш код находится на C или C ++, вы можете использовать getrusage() который возвращает вам различные статистические данные о памяти и использовании времени вашего процесса.

Не все платформы поддерживают это, и возвращают 0 значений для параметров использования памяти.

Вместо этого вы можете посмотреть виртуальный файл, созданный в /proc/[pid]/statm (где [pid] заменен идентификатором процесса. Вы можете получить это из getpid() ).

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


Еще три метода:

  1. ps aux --sort pmem
    Он сортирует результат на %MEM .
  2. ps aux | awk '{print $2, $4, $11}' | sort -k2r | head -n 15
    Он сортируется с использованием труб.
  3. top -a
    Начальная сортировка начинается с %MEM

(Извлечено here )


Как насчет time ?

Не встроенное time Bash, а одно, которое вы можете найти, с which time , например /usr/bin/time

Вот что он охватывает, на простое ls :

$ /usr/bin/time --verbose ls
(...)
Command being timed: "ls"
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:00.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): 2372
Average resident set size (kbytes): 0
Major (requiring I/O) page faults: 1
Minor (reclaiming a frame) page faults: 121
Voluntary context switches: 2
Involuntary context switches: 9
Swaps: 0
File system inputs: 256
File system outputs: 0
Socket messages sent: 0
Socket messages received: 0
Signals delivered: 0
Page size (bytes): 4096
Exit status: 0

Нет простого способа рассчитать это. Но некоторые люди пытались получить хорошие ответы:


Попробуйте команду pmap :

sudo pmap -x <process pid>

С помощью ps или аналогичных инструментов вы получите только количество страниц памяти, выделенных этим процессом. Это число верно, но:

  • не отражает фактический объем памяти, используемой приложением, только объем зарезервированной для нее памяти

  • может быть введено в заблуждение, если общие страницы, например, несколькими потоками или с использованием динамически связанных библиотек

Если вы действительно хотите узнать, какой объем памяти использует ваше приложение, вам нужно запустить его в профилировщике. Например, valgrind может дать вам представление о количестве используемой памяти и, что еще более важно, о возможных утечках памяти в вашей программе. Инструмент профилирования кучи valgrind называется «массив»:

Массив - это профилировщик кучи. Он выполняет подробное профилирование кучи, выполняя регулярные снимки кучи программы. Он создает график, показывающий использование кучи с течением времени, включая информацию о том, какие части программы отвечают за большинство распределений памяти. График дополняется текстовым или HTML-файлом, который содержит дополнительную информацию для определения того, где выделяется большая часть памяти. Massif запускает программы примерно в 20 раз медленнее, чем обычно.

Как объясняется в документации valgrind , вам нужно запустить программу через valgrind:

valgrind --tool=massif <executable> <arguments>

Massif записывает моментальные снимки использования памяти (например, massif.out.12345 ). Они обеспечивают (1) временную шкалу использования памяти, (2) для каждого моментального снимка, запись о том, где в вашей программной памяти было выделено. Отличным графическим инструментом для анализа этих файлов является massif-visualizer . Но я нашел ms_print , простой текстовый инструмент, поставляемый с valgrind, который уже очень ms_print .

Чтобы найти утечки памяти, используйте инструмент memcheck (default) memcheck для valgrind.


Это отличное резюме инструментов и проблем: archive.org link

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

Если вы хотите анализировать использование памяти всей системы или тщательно анализировать использование памяти одного приложения (а не только его использование в куче), используйте exmap . Для анализа всей системы, поиска процессов с наивысшим эффективным использованием, они набирают большую часть памяти на практике, находят процессы с наивысшим доступным для записи использованием, они создают наибольшее количество данных (и, следовательно, могут протекать или очень неэффективны при использовании данных). Выберите такое приложение и проанализируйте его отображения во втором списке. Дополнительную информацию см. В разделе exmap. Также используйте xrestop для проверки высокого уровня использования ресурсов X, особенно если процесс X-сервера занимает много памяти. Подробнее см. В разделе xrestop.

Если вы хотите обнаружить утечки, используйте valgrind или, возможно, kmtrace .

Если вы хотите проанализировать использование кучи (malloc и т. Д.) Приложения, запустите его в memprof или с помощью kmtrace , профилируйте приложение и найдите дерево вызовов функций для самых больших распределений. Подробнее см. В разделах.


Я использую htop ; это очень хорошая консольная программа, аналогичная Windows Task Manager.


Valgrind может отображать подробную информацию, но значительно замедляет целевое приложение, и большую часть времени он меняет поведение приложения.
Exmap был тем, чего я еще не знал, но кажется, что вам нужен модуль ядра для получения информации, что может быть препятствием.

Я предполагаю, что все хотят знать использование памяти WRT следующим образом ...
В linux количество физической памяти, которую может использовать один процесс, можно условно разделить на следующие категории.

  • Ma анонимная сопоставленная память

    • .p частный
      • .d грязный == malloc / mmapped куча и стек выделенная и записанная память
      • .c clean == malloc / mmapped куча и стек памяти после выделения, написания, затем освобождения, но еще не исправлены
    • .s shared
      • .d dirty == malloc / mmaped heap может получать копии на запись и совместно использовать процессы (редактируется)
      • .c clean == malloc / mmaped heap может получать копии на запись и совместно использовать процессы (редактируется)
  • Mn называется отображаемой памятью

    • .p частный
      • .d грязный == файл mmapped записанная память приватная
      • .c clean == отображаемый текст программы / библиотеки, приватно отображаемый
    • .s shared
      • .d грязный == файл mmapped записанная память совместно
      • .c чистый == сопоставленный текст библиотеки, совместно отображаемый

Утилита, включенная в Android под названием showmap , весьма полезна

virtual                    shared   shared   private  private
size     RSS      PSS      clean    dirty    clean    dirty    object
-------- -------- -------- -------- -------- -------- -------- ------------------------------
       4        0        0        0        0        0        0 0:00 0                  [vsyscall]
       4        4        0        4        0        0        0                         [vdso]
      88       28       28        0        0        4       24                         [stack]
      12       12       12        0        0        0       12 7909                    /lib/ld-2.11.1.so
      12        4        4        0        0        0        4 89529                   /usr/lib/locale/en_US.utf8/LC_IDENTIFICATION
      28        0        0        0        0        0        0 86661                   /usr/lib/gconv/gconv-modules.cache
       4        0        0        0        0        0        0 87660                   /usr/lib/locale/en_US.utf8/LC_MEASUREMENT
       4        0        0        0        0        0        0 89528                   /usr/lib/locale/en_US.utf8/LC_TELEPHONE
       4        0        0        0        0        0        0 89527                   /usr/lib/locale/en_US.utf8/LC_ADDRESS
       4        0        0        0        0        0        0 87717                   /usr/lib/locale/en_US.utf8/LC_NAME
       4        0        0        0        0        0        0 87873                   /usr/lib/locale/en_US.utf8/LC_PAPER
       4        0        0        0        0        0        0 13879                   /usr/lib/locale/en_US.utf8/LC_MESSAGES/SYS_LC_MESSAGES
       4        0        0        0        0        0        0 89526                   /usr/lib/locale/en_US.utf8/LC_MONETARY
       4        0        0        0        0        0        0 89525                   /usr/lib/locale/en_US.utf8/LC_TIME
       4        0        0        0        0        0        0 11378                   /usr/lib/locale/en_US.utf8/LC_NUMERIC
    1156        8        8        0        0        4        4 11372                   /usr/lib/locale/en_US.utf8/LC_COLLATE
     252        0        0        0        0        0        0 11321                   /usr/lib/locale/en_US.utf8/LC_CTYPE
     128       52        1       52        0        0        0 7909                    /lib/ld-2.11.1.so
    2316       32       11       24        0        0        8 7986                    /lib/libncurses.so.5.7
    2064        8        4        4        0        0        4 7947                    /lib/libdl-2.11.1.so
    3596      472       46      440        0        4       28 7933                    /lib/libc-2.11.1.so
    2084        4        0        4        0        0        0 7995                    /lib/libnss_compat-2.11.1.so
    2152        4        0        4        0        0        0 7993                    /lib/libnsl-2.11.1.so
    2092        0        0        0        0        0        0 8009                    /lib/libnss_nis-2.11.1.so
    2100        0        0        0        0        0        0 7999                    /lib/libnss_files-2.11.1.so
    3752     2736     2736        0        0      864     1872                         [heap]
      24       24       24        0        0        0       24 [anon]
     916      616      131      584        0        0       32                         /bin/bash
-------- -------- -------- -------- -------- -------- -------- ------------------------------
   22816     4004     3005     1116        0      876     2012 TOTAL

Если процесс не использует слишком много памяти (либо потому, что вы ожидаете, что это так, либо какая-либо другая команда дала эту начальную индикацию), и этот процесс может выдержать некоторое время, вы можете попытаться используйте команду gcore.

gcore <pid>

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

Это не будет работать слишком хорошо, если процесс использует сотни мегабайт или концертов, так как генерация ядра может занять несколько секунд или минут в зависимости от производительности ввода-вывода. Во время создания ядра процесс останавливается (или «заморожен»), чтобы предотвратить изменения памяти. Так что будьте осторожны.

Также убедитесь, что точка монтирования, где генерируется ядро, имеет достаточное пространство на диске и что система не будет реагировать отрицательно на основной файл, создаваемый в этом конкретном каталоге.


Я использую Arch Linux, и есть этот замечательный пакет под названием ps_mem

ps_mem -p <pid>

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

$ ps_mem -S -p $(pgrep firefox)

Private   +   Shared  =  RAM used   Swap used   Program

355.0 MiB +  38.7 MiB = 393.7 MiB    35.9 MiB   firefox
---------------------------------------------
                        393.7 MiB    35.9 MiB
=============================================

Если вам нужно что-то более быстрое, чем профилирование с Valgrind, и ваше ядро ​​старше, и вы не можете использовать smaps, ps с параметрами, чтобы показать резидентный набор процесса (с ps -o rss,command), может дать вам быстрый и разумный _aproximation_реальный объем используемая неиспользуемая память.


Изменить: это работает на 100% наилучшим образом только при увеличении потребления памяти

Если вы хотите отслеживать использование памяти с помощью данного процесса (или группы совместно используемого общего имени, например google-chrome, вы можете использовать мой bash-скрипт:

while true; do ps aux | awk ‚{print $5, $11}’ | grep chrome | sort -n > /tmp/a.txt; sleep 1; diff /tmp/{b,a}.txt; mv /tmp/{a,b}.txt; done;

это будет постоянно искать изменения и печатать их.


Используйте встроенный графический интерфейс « системный монитор », доступный в ubuntu



Хорошим тестом более «реального мира» является открытие приложения, затем запуск vmstat -sи проверка статистики «активной памяти». Закройте приложение, подождите несколько секунд и vmstat -sснова запустите . Однако значительная часть активной памяти была явно использована приложением.


Я бы предположил, что вы используете поверх. Вы можете найти все об этом на этой странице . Он способен предоставить все необходимые KPI для ваших процессов и может также захватить файл.


#!/bin/ksh
#
# Returns total memory used by process $1 in kb.
#
# See /proc/NNNN/smaps if you want to do something
# more interesting.
#

IFS=$'\n'

for line in $(</proc/$1/smaps)
do
   [[ $line =~ ^Size:\s+(\S+) ]] && ((kb += ${.sh.match[1]}))
done

print $kb




process