Як виміряти фактичне використання пам'яті програми чи процесу?


712

Це питання висвітлюється тут дуже докладно.

Як ви вимірюєте використання пам'яті програми чи процесу в Linux?

З статті блогу Розуміння використання пам'яті в Linux , psце не точний інструмент, який слід використовувати для цього.

Чому ps"неправильно"

Залежно від того, як ви на це дивитесь, psне повідомляється про реальне використання пам'яті процесів. Насправді це показує, скільки реальної пам'яті займає кожен процес, якби це був єдиний запущений процес . Звичайно, типова машина Linux має декілька десятків процесів, які працюють у будь-який момент часу, це означає, що номери VSZ та RSS, про psякі повідомляють , майже напевно помиляються .


6
Це питання, мабуть, належить на сервері defaultfault.com, а зараз, хоча це говорить мені, що "занадто стара для міграції". Не хочете насправді її закривати ...
thomasrutter

Зверніться до цього питання. stackoverflow.com/questions/669438/…
Кривавий місяць

2
Насправді psце навіть не показує - він показує номери віртуальної та резидентної пам’яті, де віртуальний - це максимальний об’єм пам’яті, який процес теоретично міг би використати, це був єдиний процес (ніколи не так), використовували кожну виділену сторінку (ніколи не буває) і не відображав чи знімав жодної сторінки (малоймовірно). У той час як резидент показує, скільки віртуальної пам'яті відображено на фізичну зараз. virt > usage > resОднак, як правило, для 64-бітної системи virt ~= res*10це дуже широкий діапазон.
Діма Тиснек

5
Уривок із пов’язаної статті - це загальна нісенітниця. RSS - це фактично використана фізична пам'ять, і VSZ може або не може перевести його на використання фізичної пам'яті, навіть якщо цей процес був єдиним запущеним.
Девід Шварц

Відповіді:


356

За допомогою psабо подібних інструментів ви отримаєте лише кількість сторінок пам'яті, виділених цим процесом. Це число правильне, але:

  • не відображає фактичний об'єм пам'яті, що використовується програмою, лише об'єм пам'яті, зарезервований для неї

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

Якщо ви дійсно хочете знати, який об'єм пам'яті насправді використовує ваша програма, вам потрібно запустити її в профілі. Наприклад, valgrindви можете отримати уявлення про кількість використовуваної пам'яті та, що ще важливіше, про можливі витоки пам'яті у вашій програмі. Купольний інструмент вальгринда називається "масивом":

Масив - це куча профілер. Він виконує детальну групування профілю шляхом регулярних знімків купи програми. Він створює графік, що відображає використання купи за часом, включаючи інформацію про те, які частини програми відповідають за найбільше розподілу пам'яті. Графік доповнений текстовим або HTML-файлом, який містить додаткову інформацію для визначення місця виділення найбільшої пам’яті. Massif запускає програми приблизно в 20 разів повільніше, ніж зазвичай.

Як пояснено в документації про valgrind , програму потрібно запустити через valgrind:

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

Massif пише дамп знімків із використання пам'яті (наприклад massif.out.12345). Вони забезпечують (1) часову шкалу використання пам'яті, (2) для кожного знімка, запис про те, де в програмі була виділена пам'ять. Прекрасним графічним інструментом для аналізу цих файлів є масив-візуалізатор . Але я виявив ms_print, що простий текстовий інструмент, що постачається з вальгрингом, вже є дуже корисним.

Щоб знайти витоки пам'яті, використовуйте memcheckінструмент valgrind (за замовчуванням) .


44
Для інтерпретації результатів, породжених вальгриндом, я можу порекомендувати aleyoop. Це не надто вигадливо, і говорить просто, що вам потрібно знати, щоб знайти джерела витоків. Приємна пара комунальних послуг.
День

6
Пункт (а) правильний. Існує різниця між використовуваними сторінками та пам'яттю, фактично виділеною програмою за допомогою дзвінків на malloc (), нові тощо. Використання резидента просто показує, яка частина пам'яті, що підключається до сторінки, знаходиться в оперативній пам'яті.
jcoffland

63
Це насправді не говорить про те, як отримати пам'ять за допомогою valgrind?
Метт Столяр

11
інструмент valgrind за замовчуванням, memcheck, корисний для виявлення витоків пам’яті, але він насправді не є профілером пам'яті. Для цього потрібно valgrind --tool = масив.
Тодд Фрід

3
@DavidSchwartz Я не бачу, як ваше твердження суперечить моєму. У мене таке відчуття, що ти занадто сильно переймаєшся тим, що ти вважаєш себе неправим, ніж насправді читаєш те, що я говорю. Я весь суть у тому, що RSS - це неправильна міра для реального використання пам’яті програми, і ви висуваєте той самий пункт у своїх останніх двох реченнях. Дійсно, що ви навіть думали, що це стало причиною того, що я в першу чергу викликав усадку RSS? Так що ви мені це вимовляєте, щоб довести мене "неправильно" саме тією річчю, про яку я маю на увазі? Ваше ставлення до мене стомлює.
ypnos

280

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

sudo pmap -x <process pid>

45
запустити з судо, або він не дає помилок і не показує, що пам'ять не витрачається.
Метт

22
Не існує на OSX (для тих, хто приходить сюди з google)
jcollum

3
Це повна відповідь на питання! пс. У своїй оболонці pmap може читати процес без судо.
MasterControlProgram

7
Щодо OS X (здається, це не хвилює ОП), ви можете побачити деякі подібні дані, використовуючи vmmap (1)
jrg

Примітка: дає зовсім іншу відповідь відgnome-system-monitor
ribamar

190

Важко сказати точно, але ось дві "близькі" речі, які можуть допомогти.

$ ps aux 

дасть вам віртуальний розмір (VSZ)

Ви також можете отримати детальну статистику з / proc файлової системи, перейшовши до /proc/$pid/status

Найважливішим є VmSize, який повинен бути близьким до того, що ps auxдає.

/ proc / 19420 $ статус кота
Назва: firefox
Стан: S (спальний)
Твердий: 19420
Під: 19420 рік
ППід: 1
TracerPid: 0
Uid: 1000 1000 1000 1000
Гід: 1000 1000 1000 1000
Розмір FDS: 256
Групи: 4 6 20 24 25 29 30 44 46 107 109 115 124 1000 
VmPeak: 222956 кБ
VmSize: 212520 кБ
VmLck: 0 кБ
VmHWM: 127912 кБ
VmRSS: 118768 кБ
VmData: 170180 кБ
VmStk: 228 кБ
VmExe: 28 кБ
VmLib: 35424 кБ
VmPTE: 184 кБ
Нитки: 8
SigQ: 0/16382
Підпис: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
Знак: 0000000020001000
SigCgt: 000000018000442f
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
Cpus_allowed: 03
Mems_allowed: 1
добровільні_ctxt_switches: 63422
невольові_перевірки_ 7: 1


21
Я щось пропускаю? Питання задавало питання, як краще виміряти використання пам'яті процесом, враховуючи, що VSZ та RSS, повідомлені у ps, вводять в оману. Ваша відповідь детально розказує, як шукати VSZ - те саме значення, яке згадувалося як оману.
thomasrutter

16
@thomasrutter Так, вам не вистачає оригінального питання (rev 1), воно було відредаговано кілька разів і є досить старим (2008). В оригінальному запитанні якраз було задано питання про те, як виміряти використання пам'яті процесу. Хоча ви можете редагувати питання та відповіді, якщо речі застаріли. :)
DustinB

1
Примітка: дає зовсім іншу відповідь відgnome-system-monitor
ribamar

131

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

cat /proc/1234/smaps

Він точно скаже, скільки пам’яті він використовує на той час. Що ще важливіше, він розділить пам'ять на приватну та спільну, тому ви можете сказати, скільки пам'яті використовує ваш екземпляр програми, не враховуючи пам'ять, поділену між кількома екземплярами програми.


Я думаю, pmapце більш простий інтерфейс до нього.
рибамар

126

Простий спосіб обчислити це не існує. Але деякі люди намагалися отримати хороші відповіді:


приємно виводить чистий список пам’яті та процесу
Rubytastic

Дуже приємно, з досить розумним групуванням.
Ромер

Так, справді дуже приємно. Я вважаю ps_memі smemдуже корисним для заходів кінцевого споживача, хоча, наприклад, pmapДуже детальний вихід орієнтований на розробники ... дозволяє відновити використання пам'яті Firefox для кожного шрифту, аддону, лібрики для екс. Дякую всім досвіду @Bash, @thomasruther.
tuk0z

цей поки що єдиний, який відповідає результатуgnome-system-monitor
ribamar

110

Використовуйте smem , який є альтернативою ps, який обчислює USS та PSS за процес. Те, що ви хочете, це, ймовірно, PSS.

  • USS - унікальний розмір набору. Це кількість неподіленої пам'яті, унікальна для цього процесу (подумайте про це як U для унікальної пам'яті). Він не включає спільну пам'ять. Таким чином , це буде під -report обсяг пам'яті процесу , використання, але корисно , якщо ви хочете ігнорувати загальну пам'ять.

  • PSS - пропорційний розмір набору. Це те, що ти хочеш. Він поєднує унікальну пам'ять (USS), а також частку її спільної пам'яті, поділену на кількість процесів, що діляться цією пам'яттю. Таким чином, воно дасть точне уявлення про те, скільки фактичної фізичної пам’яті використовується за один процес - при цьому спільна пам'ять справді представлена ​​як спільна. Подумайте про буття Р для фізичної пам’яті.

Як це порівнюється з RSS як повідомляють ps та інші утиліти:

  • RSS - розмір постійного набору Це об'єм спільної пам’яті плюс неділена пам'ять, що використовується кожним процесом. Якщо будь-які процеси поділяють пам’ять, це надмірно звітує про кількість фактично використовуваної пам'яті, оскільки однакова спільна пам'ять буде рахуватися не один раз - знову з'являться в одному з інших процесів, які мають спільну пам'ять. Таким чином, це досить ненадійно, особливо коли процеси з високою пам'яттю мають багато вилок - що є звичайним на сервері, з такими процесами, як Apache або PHP (fastcgi / FPM).

Зауважте: smem може також (необов'язково) виводити графіки, такі як кругові діаграми тощо. ІМО вам нічого з цього не потрібно. Якщо ви просто хочете використовувати його з командного рядка, як ви можете використовувати ps -A v, то вам не потрібно встановлювати рекомендовану залежність python-matplotlib.


2
Одним з важливих моментів щодо RSS є те, що більшість програм сьогодні використовує багато кодових сторінок. Кожна спільна бібліотека (наприклад, libc та libstdc ++) буде враховуватися за кожен процес її використання. І якщо є кілька примірників запущеного процесу, весь цей код буде подвійний.
Девід К.

1
Саме тому, надмірно RSS-звіти щодо фактичної фізичної пам'яті за процес.
thomasrutter

3
smem - це те, що мені було потрібно. Запускаючи його з -t кожного разу, коли я запускаю новий екземпляр процесу, я бачу пам'ять, яку споживає кожен екземпляр. Для chrome: smem -t -P '/ opt / google / chrome'
xtian

У мене важко знайти документацію для smem .. чи виводиться вона у байтах, кілобайтах чи мегабайтах за замовчуванням ??
ZN13

4
TL; DR: USS = Кількість фізичної пам'яті, яка буде звільнена, якщо процес буде вбитий, PSS = Кількість фізичної пам'яті, яка потрібна цьому процесу від системи, якщо жодні існуючі процеси не будуть вбиті, RSS = Кількість фізичної пам'яті, доступною для цей процес (але не завжди ексклюзивний доступ).
Мікко Ранталайнен

95
ps -eo size,pid,user,command --sort -size | \
    awk '{ hr=$1/1024 ; printf("%13.2f Mb ",hr) } { for ( x=4 ; x<=NF ; x++ ) { printf("%s ",$x) } print "" }' |\
    cut -d "" -f2 | cut -d "-" -f1

Використовуйте це як корінь, і ви можете отримати чіткий вихід для використання пам'яті кожним процесом.

ПРИКЛАД ВИХІДУ:

     0.00 Mb COMMAND 
  1288.57 Mb /usr/lib/firefox
   821.68 Mb /usr/lib/chromium/chromium 
   762.82 Mb /usr/lib/chromium/chromium 
   588.36 Mb /usr/sbin/mysqld 
   547.55 Mb /usr/lib/chromium/chromium 
   523.92 Mb /usr/lib/tracker/tracker
   476.59 Mb /usr/lib/chromium/chromium 
   446.41 Mb /usr/bin/gnome
   421.62 Mb /usr/sbin/libvirtd 
   405.11 Mb /usr/lib/chromium/chromium 
   302.60 Mb /usr/lib/chromium/chromium 
   291.46 Mb /usr/lib/chromium/chromium 
   284.56 Mb /usr/lib/chromium/chromium 
   238.93 Mb /usr/lib/tracker/tracker
   223.21 Mb /usr/lib/chromium/chromium 
   197.99 Mb /usr/lib/chromium/chromium 
   194.07 Mb conky 
   191.92 Mb /usr/lib/chromium/chromium 
   190.72 Mb /usr/bin/mongod 
   169.06 Mb /usr/lib/chromium/chromium 
   155.11 Mb /usr/bin/gnome
   136.02 Mb /usr/lib/chromium/chromium 
   125.98 Mb /usr/lib/chromium/chromium 
   103.98 Mb /usr/lib/chromium/chromium 
    93.22 Mb /usr/lib/tracker/tracker
    89.21 Mb /usr/lib/gnome
    80.61 Mb /usr/bin/gnome
    77.73 Mb /usr/lib/evolution/evolution
    76.09 Mb /usr/lib/evolution/evolution
    72.21 Mb /usr/lib/gnome
    69.40 Mb /usr/lib/evolution/evolution
    68.84 Mb nautilus
    68.08 Mb zeitgeist
    60.97 Mb /usr/lib/tracker/tracker
    59.65 Mb /usr/lib/evolution/evolution
    57.68 Mb apt
    55.23 Mb /usr/lib/gnome
    53.61 Mb /usr/lib/evolution/evolution
    53.07 Mb /usr/lib/gnome
    52.83 Mb /usr/lib/gnome
    51.02 Mb /usr/lib/udisks2/udisksd 
    50.77 Mb /usr/lib/evolution/evolution
    50.53 Mb /usr/lib/gnome
    50.45 Mb /usr/lib/gvfs/gvfs
    50.36 Mb /usr/lib/packagekit/packagekitd 
    50.14 Mb /usr/lib/gvfs/gvfs
    48.95 Mb /usr/bin/Xwayland :1024 
    46.21 Mb /usr/bin/gnome
    42.43 Mb /usr/bin/zeitgeist
    42.29 Mb /usr/lib/gnome
    41.97 Mb /usr/lib/gnome
    41.64 Mb /usr/lib/gvfs/gvfsd
    41.63 Mb /usr/lib/gvfs/gvfsd
    41.55 Mb /usr/lib/gvfs/gvfsd
    41.48 Mb /usr/lib/gvfs/gvfsd
    39.87 Mb /usr/bin/python /usr/bin/chrome
    37.45 Mb /usr/lib/xorg/Xorg vt2 
    36.62 Mb /usr/sbin/NetworkManager 
    35.63 Mb /usr/lib/caribou/caribou 
    34.79 Mb /usr/lib/tracker/tracker
    33.88 Mb /usr/sbin/ModemManager 
    33.77 Mb /usr/lib/gnome
    33.61 Mb /usr/lib/upower/upowerd 
    33.53 Mb /usr/sbin/gdm3 
    33.37 Mb /usr/lib/gvfs/gvfsd
    33.36 Mb /usr/lib/gvfs/gvfs
    33.23 Mb /usr/lib/gvfs/gvfs
    33.15 Mb /usr/lib/at
    33.15 Mb /usr/lib/at
    30.03 Mb /usr/lib/colord/colord 
    29.62 Mb /usr/lib/apt/methods/https 
    28.06 Mb /usr/lib/zeitgeist/zeitgeist
    27.29 Mb /usr/lib/policykit
    25.55 Mb /usr/lib/gvfs/gvfs
    25.55 Mb /usr/lib/gvfs/gvfs
    25.23 Mb /usr/lib/accountsservice/accounts
    25.18 Mb /usr/lib/gvfs/gvfsd 
    25.15 Mb /usr/lib/gvfs/gvfs
    25.15 Mb /usr/lib/gvfs/gvfs
    25.12 Mb /usr/lib/gvfs/gvfs
    25.10 Mb /usr/lib/gnome
    25.10 Mb /usr/lib/gnome
    25.07 Mb /usr/lib/gvfs/gvfsd 
    24.99 Mb /usr/lib/gvfs/gvfs
    23.26 Mb /usr/lib/chromium/chromium 
    22.09 Mb /usr/bin/pulseaudio 
    19.01 Mb /usr/bin/pulseaudio 
    18.62 Mb (sd
    18.46 Mb (sd
    18.30 Mb /sbin/init 
    18.17 Mb /usr/sbin/rsyslogd 
    17.50 Mb gdm
    17.42 Mb gdm
    17.09 Mb /usr/lib/dconf/dconf
    17.09 Mb /usr/lib/at
    17.06 Mb /usr/lib/gvfs/gvfsd
    16.98 Mb /usr/lib/at
    16.91 Mb /usr/lib/gdm3/gdm
    16.86 Mb /usr/lib/gvfs/gvfsd
    16.86 Mb /usr/lib/gdm3/gdm
    16.85 Mb /usr/lib/dconf/dconf
    16.85 Mb /usr/lib/dconf/dconf
    16.73 Mb /usr/lib/rtkit/rtkit
    16.69 Mb /lib/systemd/systemd
    13.13 Mb /usr/lib/chromium/chromium 
    13.13 Mb /usr/lib/chromium/chromium 
    10.92 Mb anydesk 
     8.54 Mb /sbin/lvmetad 
     7.43 Mb /usr/sbin/apache2 
     6.82 Mb /usr/sbin/apache2 
     6.77 Mb /usr/sbin/apache2 
     6.73 Mb /usr/sbin/apache2 
     6.66 Mb /usr/sbin/apache2 
     6.64 Mb /usr/sbin/apache2 
     6.63 Mb /usr/sbin/apache2 
     6.62 Mb /usr/sbin/apache2 
     6.51 Mb /usr/sbin/apache2 
     6.25 Mb /usr/sbin/apache2 
     6.22 Mb /usr/sbin/apache2 
     3.92 Mb bash 
     3.14 Mb bash 
     2.97 Mb bash 
     2.95 Mb bash 
     2.93 Mb bash 
     2.91 Mb bash 
     2.86 Mb bash 
     2.86 Mb bash 
     2.86 Mb bash 
     2.84 Mb bash 
     2.84 Mb bash 
     2.45 Mb /lib/systemd/systemd
     2.30 Mb (sd
     2.28 Mb /usr/bin/dbus
     1.84 Mb /usr/bin/dbus
     1.46 Mb ps 
     1.21 Mb openvpn hackthebox.ovpn 
     1.16 Mb /sbin/dhclient 
     1.16 Mb /sbin/dhclient 
     1.09 Mb /lib/systemd/systemd 
     0.98 Mb /sbin/mount.ntfs /dev/sda3 /media/n0bit4/Data 
     0.97 Mb /lib/systemd/systemd 
     0.96 Mb /lib/systemd/systemd 
     0.89 Mb /usr/sbin/smartd 
     0.77 Mb /usr/bin/dbus
     0.76 Mb su 
     0.76 Mb su 
     0.76 Mb su 
     0.76 Mb su 
     0.76 Mb su 
     0.76 Mb su 
     0.75 Mb sudo su 
     0.75 Mb sudo su 
     0.75 Mb sudo su 
     0.75 Mb sudo su 
     0.75 Mb sudo su 
     0.75 Mb sudo su 
     0.74 Mb /usr/bin/dbus
     0.71 Mb /usr/lib/apt/methods/http 
     0.68 Mb /bin/bash /usr/bin/mysqld_safe 
     0.68 Mb /sbin/wpa_supplicant 
     0.66 Mb /usr/bin/dbus
     0.61 Mb /lib/systemd/systemd
     0.54 Mb /usr/bin/dbus
     0.46 Mb /usr/sbin/cron 
     0.45 Mb /usr/sbin/irqbalance 
     0.43 Mb logger 
     0.41 Mb awk { hr=$1/1024 ; printf("%13.2f Mb ",hr) } { for ( x=4 ; x<=NF ; x++ ) { printf("%s ",$x) } print "" } 
     0.40 Mb /usr/bin/ssh
     0.34 Mb /usr/lib/chromium/chrome
     0.32 Mb cut 
     0.32 Mb cut 
     0.00 Mb [kthreadd] 
     0.00 Mb [ksoftirqd/0] 
     0.00 Mb [kworker/0:0H] 
     0.00 Mb [rcu_sched] 
     0.00 Mb [rcu_bh] 
     0.00 Mb [migration/0] 
     0.00 Mb [lru
     0.00 Mb [watchdog/0] 
     0.00 Mb [cpuhp/0] 
     0.00 Mb [cpuhp/1] 
     0.00 Mb [watchdog/1] 
     0.00 Mb [migration/1] 
     0.00 Mb [ksoftirqd/1] 
     0.00 Mb [kworker/1:0H] 
     0.00 Mb [cpuhp/2] 
     0.00 Mb [watchdog/2] 
     0.00 Mb [migration/2] 
     0.00 Mb [ksoftirqd/2] 
     0.00 Mb [kworker/2:0H] 
     0.00 Mb [cpuhp/3] 
     0.00 Mb [watchdog/3] 
     0.00 Mb [migration/3] 
     0.00 Mb [ksoftirqd/3] 
     0.00 Mb [kworker/3:0H] 
     0.00 Mb [kdevtmpfs] 
     0.00 Mb [netns] 
     0.00 Mb [khungtaskd] 
     0.00 Mb [oom_reaper] 
     0.00 Mb [writeback] 
     0.00 Mb [kcompactd0] 
     0.00 Mb [ksmd] 
     0.00 Mb [khugepaged] 
     0.00 Mb [crypto] 
     0.00 Mb [kintegrityd] 
     0.00 Mb [bioset] 
     0.00 Mb [kblockd] 
     0.00 Mb [devfreq_wq] 
     0.00 Mb [watchdogd] 
     0.00 Mb [kswapd0] 
     0.00 Mb [vmstat] 
     0.00 Mb [kthrotld] 
     0.00 Mb [ipv6_addrconf] 
     0.00 Mb [acpi_thermal_pm] 
     0.00 Mb [ata_sff] 
     0.00 Mb [scsi_eh_0] 
     0.00 Mb [scsi_tmf_0] 
     0.00 Mb [scsi_eh_1] 
     0.00 Mb [scsi_tmf_1] 
     0.00 Mb [scsi_eh_2] 
     0.00 Mb [scsi_tmf_2] 
     0.00 Mb [scsi_eh_3] 
     0.00 Mb [scsi_tmf_3] 
     0.00 Mb [scsi_eh_4] 
     0.00 Mb [scsi_tmf_4] 
     0.00 Mb [scsi_eh_5] 
     0.00 Mb [scsi_tmf_5] 
     0.00 Mb [bioset] 
     0.00 Mb [kworker/1:1H] 
     0.00 Mb [kworker/3:1H] 
     0.00 Mb [kworker/0:1H] 
     0.00 Mb [kdmflush] 
     0.00 Mb [bioset] 
     0.00 Mb [kdmflush] 
     0.00 Mb [bioset] 
     0.00 Mb [jbd2/sda5
     0.00 Mb [ext4
     0.00 Mb [kworker/2:1H] 
     0.00 Mb [kauditd] 
     0.00 Mb [bioset] 
     0.00 Mb [drbd
     0.00 Mb [irq/27
     0.00 Mb [i915/signal:0] 
     0.00 Mb [i915/signal:1] 
     0.00 Mb [i915/signal:2] 
     0.00 Mb [ttm_swap] 
     0.00 Mb [cfg80211] 
     0.00 Mb [kworker/u17:0] 
     0.00 Mb [hci0] 
     0.00 Mb [hci0] 
     0.00 Mb [kworker/u17:1] 
     0.00 Mb [iprt
     0.00 Mb [iprt
     0.00 Mb [kworker/1:0] 
     0.00 Mb [kworker/3:0] 
     0.00 Mb [kworker/0:0] 
     0.00 Mb [kworker/2:0] 
     0.00 Mb [kworker/u16:0] 
     0.00 Mb [kworker/u16:2] 
     0.00 Mb [kworker/3:2] 
     0.00 Mb [kworker/2:1] 
     0.00 Mb [kworker/1:2] 
     0.00 Mb [kworker/0:2] 
     0.00 Mb [kworker/2:2] 
     0.00 Mb [kworker/0:1] 
     0.00 Mb [scsi_eh_6] 
     0.00 Mb [scsi_tmf_6] 
     0.00 Mb [usb
     0.00 Mb [bioset] 
     0.00 Mb [kworker/3:1] 
     0.00 Mb [kworker/u16:1] 

1
Будь-який спосіб відфільтрувати список так, щоб мати лише процеси, які використовують більше 25% пам'яті для скажімо 30-х років? Я намагаюся бачити ті, що не втікають процеси, як-от браузер Chrome при використанні налагоджувача PHPEclipse.
Стефан

цей фільтр був би приголомшливим
aleix

1
Я опублікую це, як тільки зможу.
Lokendra Singh Rawat

2
Чудово! Але цикл повинен починатися з того, x=2щоб також виводити pid та користувача.
Борис Бродський

70

Про що time?

Наприклад, не Bash вбудований, timeа той, який ви можете знайти 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

Я також. Це те, як я використовую для профілювання завдань у powercron.eu :)
Moonchild

5
brew install gnu-timeтоді використовуйте, gtimeякщо ви перебуваєте на macOS.
Нобу

4
Недолік: Не отримаєте результати до тих пір, поки процес не завершить його виконання. Неможливо використовувати для моніторингу запущеного процесу в реальному часі.
Makesh

/ usr / bin / time -f '% M'
infomaniac

1
Ви також можете викликати його за допомогою \ time (зі зворотною косою рискою, щоб не використовувати внутрішній час оболонки).
Рауль Салінас-Монтеагудо

39

Це чудовий підсумок інструментів та проблем: посилання archive.org

Я цитую його, щоб більше чортів насправді його прочитали.

Якщо ви хочете проаналізувати використання пам’яті всієї системи або ретельно проаналізувати використання пам’яті однієї програми (а не лише її нагромадження), використовуйте exmap . Для цілого системного аналізу знайдіть процеси з найвищим ефективним використанням, вони займають найбільше пам’яті на практиці, знаходять процеси з найвищим рівнем запису, вони створюють найбільше даних (і, отже, можливо, протікають або є дуже неефективними при використанні даних). Виберіть таку програму та проаналізуйте її відображення у другому перегляді списку. Детальнішу інформацію див. У розділі exmap. Також використовуйте xrestop для перевірки високого використання ресурсів X, особливо якщо процес X-сервера займає багато пам'яті. Докладніше див. У розділі xrestop.

Якщо ви хочете виявити протікання, використовуйте valgrind або можливо кмтрас .

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


28

Поруч із рішеннями, переліченими у ваших відповідях, ви можете скористатися командою Linux "верх"; Він забезпечує динамічний перегляд в реальному часі запущеної системи, дає використання процесора та пам'яті для всієї системи, а також для кожної програми у відсотках:

top

для фільтра за допомогою pid програми:

top -p <PID>

для фільтра за назвою програми:

top | grep <PROCESS NAME>

"top" надає також деякі поля, такі як:

VIRT - Віртуальне зображення (kb): загальна кількість віртуальної пам'яті, яка використовується завданням

RES - розмір резидента (kb): фізична пам’ять, що не замінюється, завдання, яке використовується; RES = КОД + ДАНІ.

DATA - Data + Stack size (kb): Обсяг фізичної пам'яті, виділений на інший, ніж виконуваний код, також відомий як "розмір набору даних" або DRS.

SHR - Розмір спільної пам’яті (кб): кількість спільної пам’яті, яка використовується завданням. Він просто відображає пам'ять, яка потенційно може бути поділена з іншими процесами.

Довідка тут .


20

На це немає однозначної відповіді, оскільки ви не можете точно вказати кількість пам'яті, яку використовує процес. Більшість процесів під Linux використовує спільні бібліотеки. Наприклад, скажімо, що ви хочете обчислити використання пам'яті для 'ls' процесу. Чи вважаєте ви лише пам'ять, яку використовує виконуваний 'ls' (якщо ви могли його ізолювати)? Як щодо libc? Або всі ці інші лібси, які потрібні для запуску "ls"?

linux-gate.so.1 =>  (0x00ccb000)
librt.so.1 => /lib/librt.so.1 (0x06bc7000)
libacl.so.1 => /lib/libacl.so.1 (0x00230000)
libselinux.so.1 => /lib/libselinux.so.1 (0x00162000)
libc.so.6 => /lib/libc.so.6 (0x00b40000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00cb4000)
/lib/ld-linux.so.2 (0x00b1d000)
libattr.so.1 => /lib/libattr.so.1 (0x00229000)
libdl.so.2 => /lib/libdl.so.2 (0x00cae000)
libsepol.so.1 => /lib/libsepol.so.1 (0x0011a000)

Ви можете стверджувати, що вони поділяються іншими процесами, але 'ls' неможливо запустити в системі без завантаження.

Крім того, якщо вам потрібно знати, скільки пам'яті потрібно процесу для планування ємності, вам доведеться підрахувати, скільки використовує кожна додаткова копія процесу. Я думаю, що / proc / PID / статус може одночасно дати вам достатню інформацію про використання пам'яті. З іншого боку, valgrind надасть вам кращий профіль використання пам’яті протягом усього життя програми


я намагаюся знайти, скільки пам’яті займає процес VM і хочу використовувати це для встановлення межі пам’яті в кубернетах, я згоден на цю відповідь, тому буду використовувати пам’ять, показануpmap
Deepak Deore

16

Якщо ваш код знаходиться на C або C ++, ви, можливо, зможете використовувати, getrusage()що повертає вам різні статистичні дані щодо пам’яті та часу використання вашого процесу.

Не всі платформи підтримують це, хоча повернуть 0 значень для параметрів використання пам'яті.

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

Цей файл буде схожий на текстовий файл із 7 цілими числами. Вас, мабуть, найбільше цікавлять перші (усі пам'яті) та шості (використання пам'яті даних) у цьому файлі.


Зауважте, що це підтримується не на всіх платформах.
CashCow

Відповідно до сторінки людини Linux ( linux.die.net/man/2/getrusage ), getrusage є частиною специфікацій SVr4, 4.3BSD та POSIX.1-2001 (зазначаючи, що POSIX вказує лише поля часу та часу.) I не очікував би, що він буде працювати на не-UNIX-платформах (за винятком, можливо, через середовища, як Cygwin, що забезпечує можливості UNIX для інших платформ.)
David C.

@DavidC. ОП запитує про Linux.
Алексіс Вілке

@CashCow, ви мали на увазі getpid(), тому що я не знаю getprocessid()функції в C / C ++ під Linux.
Алексіс Вілке

12

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

Я припускаю, що всі хочуть знати WRT "використання пам'яті", це наступне ...
У Linux, кількість фізичної пам'яті, яку може використовувати один процес, можна приблизно поділити на наступні категорії.

  • Ма анонімна карта пам'яті

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

    • .p приватний
      • .d брудний == файл mmapped письмова пам'ять приватна
      • .c clean == відображений приватний текст програми / бібліотеки
    • .s
      • .d dirty == файл mmapped письмовою пам'яттю спільно
      • .c clean == відображений текст бібліотеки, спільний відображений

Утиліта, що входить в 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

10

Ще три способи спробувати:

  1. ps aux --sort pmem
    Він сортує вихід по %MEM.
  2. ps aux | awk '{print $2, $4, $11}' | sort -k2r | head -n 15
    Він сортує за допомогою труб.
  3. top -a
    Починається верхнє сортування за %MEM

(Витягнуто звідси )


2
topі, ймовірно, інші не дають точного зображення пам’яті, яка фактично використовується процесом. Наприклад, у мене 64 Гбіт оперативної пам’яті, і я маю 10 postgresпроцесів, які повідомляють про ВІД 16 Гбіб і 25% ПДО. Звичайно, вони не можуть використовувати 25% ... Кожен також має 15GiB SHR, і, здається, вони поділяють це.
судо

8
#!/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

5
ksh - це стандартна оболонка. Він може не встановлюватися за замовчуванням у Linux- дистрибутивах для користувачів настільних ПК або для мінімалістичних цілей, але це лише одна команда майже в будь-якій ОС Unix- / linux. (тобто на всіх BSD, на всіх реальних UNIX, на RHEL, на SLES, на Debian, на Ubuntu, на OSX)
Florian Heigl

Цей файл доступний за замовчуванням лише користувачу root.
Дмитро Гінзбург

Далі якраз переписане вище sed | awkта працює в Busybox v1.23.2: sed -n 's/^Size:\s\+\(\S\+\) .*/\1/p' /proc/$1/smaps | awk '{s+=$1} END {print s}'
Ján Sáreník

1
@Catskul - Стандарт POSIX визначає його стандартну оболонку як сувору підмножину оболонки Korn, вдосконаленої версії оболонки Bourne.
ceph3us

8

Я використовую htop; це дуже хороша консольна програма, схожа на Windows Task Manager.


Я використовував htopі є кращим за топ, але все одно він покаже вам всі теми з різних додатків, не групуючи їх, роблячи це майже таким же марним, як топ.
sorin

1
$ htop -p $ (pgrep <ваше ім'я процесу> | xargs | tr '' ',')
AAAfarmclub

6

Якщо процес не використовує занадто багато пам'яті (або тому, що ви очікуєте, що це так, або якась інша команда дала цю початкову вказівку), і процес може витримати зупинку на короткий проміжок часу, ви можете спробувати використовувати команду gcore.

gcore <pid>

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

Це не спрацює надто добре, якщо процес використовує сотні мегів або концертів, оскільки для створення основного пристрою може знадобитися кілька секунд або хвилин, залежно від продуктивності вводу / виводу. Під час створення ядра процес зупиняється (або «заморожується»), щоб запобігти зміні пам’яті. Тож будьте обережні.

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


6

Я використовую 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
=============================================

5

Нижче командний рядок дасть вам загальну пам’ять, яку використовує різноманітний процес, що працює на машині Linux у MB

ps -eo size,pid,user,command --sort -size | awk '{ hr=$1/1024 ; printf("%13.2f Mb ",hr) } { for ( x=4 ; x<=NF ; x++ ) { printf("%s ",$x) } print "" }' | awk '{total=total + $1} END {print total}'

5

Хорошим тестом на використання більш "реального світу" є відкриття програми, запуску vmstat -sта перевірка статистики "активної пам'яті". Закрийте програму, зачекайте кілька секунд і запустіть vmstat -sзнову. Однак значно активніша пам'ять була звільнена від програми.


3
Як би це було краще, ніж ps ?? Він поставляється з усією обмеженістю PS і ще більш неточний ...
Лестер Чеун

У типовій системі Unix багато часу починається і закінчується процес. Ви не можете передбачити безкоштовну оперативну пам’ять.
Рауль Салінас-Монтеагудо

4

Отримайте вальгринд. дайте програмі запустити програму, і вона розкаже вам багато про її використання пам'яті.

Це стосується лише випадку програми, яка працює деякий час і зупиняється. Я не знаю, чи може valgrind взяти участь у вже запущеному процесі чи не повинен зупиняти такі процеси, як демони.


Ні, не можна "прикріпити" вальгринд до запущеного процесу. Це за дизайном.
Діма Тиснек

3

Редагувати: це працює на 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;

це буде постійно шукати зміни та друкувати їх.

введіть тут опис зображення


3

Якщо ви хочете чогось швидшого, ніж профайлювання за допомогою Valgrind, і ваше ядро ​​старше, і ви не можете використовувати smaps, ps із варіантами показу резидентного набору процесу (з ps -o rss,command) може дати вам швидкий і розумний _aproximation_реальний обсяг не використовується обмін пам'яті, що використовується.


3

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


2
Щоб показати PSIZE ["пропорційний розмір пам'яті цього процесу (або користувача)], запустіть зверху за допомогою atop -R. Щоб показати підсумковий підсумок користувача p, сортувати за натисканням використання пам'яті" M "зсередини зверху. Це дає аналогічні числа, ніж smem.
Маркус Штраус


1

Ще один голос за тут, але хотілося б додати, що ви можете використовувати такий інструмент, як Alleyoop, щоб допомогти вам інтерпретувати результати, породжені valgrind.

Я використовую ці два інструменти весь час і завжди маю пісний, непротікаючий код, щоб гордо показати його;)


1

Хоча це питання, мабуть, стосується вивчення поточно запущених процесів, я хотів побачити пікову пам'ять, яку використовує програма від початку до кінця. Крім valgrind, ви можете використовувати tstime , що набагато простіше. Він вимірює використання "висоководного" пам'яті (RSS та віртуальної). З цієї відповіді .


Більшість програм - тобто ті, які використовують malloc () та malloc-подібні бібліотеки пам'яті - не повертають сторінки в ОС до завершення роботи. Таким чином, сума, яку ви побачите в PS (або будь-якому іншому інструменті, який не копається в купу), буде високим рівнем води.
Девід К.

0

На основі відповіді на пов'язане питання .

Ви можете використовувати SNMP для отримання пам'яті та використання процесора у певному пристрої в мережі :)

Вимоги:

  • на пристрої, що запускає процес, має бути встановлено та запущено snmp
  • snmp має бути налаштований на прийняття запитів, звідки ви запустите скрипт нижче (він може бути налаштований у snmpd.conf)
  • ви повинні знати ідентифікатор процесу (pid) процесу, який ви хочете контролювати

Примітки:

  • HOST-RESOURCES-MIB :: hrSWRunPerfCPU - це кількість сантиметрових секунд загальних ресурсів ЦП, що споживаються цим процесом. Зауважте, що в багатопроцесорній системі це значення може зростати більше ніж на одну центісекундну частину за одну центні секунди реального часу (настінні годинники).

  • HOST-RESOURCES-MIB :: hrSWRunPerfMem - це загальна кількість реальної системної пам'яті, виділеної на цей процес.

**

Сценарій моніторингу процесів:

**

echo "IP: "
read ip
echo "specfiy pid: "
read pid
echo "interval in seconds:"
read interval

while [ 1 ]
do
    date
    snmpget -v2c -c public $ip HOST-RESOURCES-MIB::hrSWRunPerfCPU.$pid
    snmpget -v2c -c public $ip HOST-RESOURCES-MIB::hrSWRunPerfMem.$pid
    sleep $interval;
done

0

/ prox / xxx / numa_maps дає там інформацію: N0 = ??? N1 = ??? Але цей результат може бути нижчим за фактичний результат, оскільки він враховує лише ті, які торкнулися.


-1

Використовуйте вбудований інструмент GUI ' монітор системи ', доступний в ubuntu


1
Принаймні з 16.04 це дуже добре працює. Хоча це дуже схоже на вершину, використовувана пам'ять не надзвичайно точна ...
Алексіс Вілке
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.