Linux: Total swap використовується = swap використовується процесами +?


17

Отже, я намагаюся провести деяке розслідування щодо того, звідки походить використання swap у системі з високим використанням swap:

# free
             total       used       free     shared    buffers     cached
Mem:        515324     508800       6524          0       4852      27576
-/+ buffers/cache:     476372      38952
Swap:       983032     503328     479704

Додавання заміни, що використовується в процесі:

# for proc in /proc/*; do cat $proc/smaps 2>/dev/null | awk '/Swap/{swap+=$2}END{print swap "\t'`readlink $proc/exe`'"}'; done | sort -n | awk '{total+=$1}/[0-9]/;END{print total "\tTotal"}'
0       /bin/gawk
0       /bin/sort
0       /usr/bin/readlink
28      /sbin/xxxxxxxx
52      /sbin/mingetty
52      /sbin/mingetty
52      /sbin/mingetty
52      /sbin/mingetty
56      /sbin/mingetty
56      /sbin/mingetty
60      /xxxxxxxxxxx
60      /usr/sbin/xxx
84      /usr/sbin/xxx
108     /usr/bin/xxx
168     /bin/bash
220     /sbin/init
256     /sbin/rsyslogd
352     /bin/bash
356     /bin/bash
360     /usr/sbin/sshd
496     /usr/sbin/crond
672     /usr/sbin/sshd
12972   /opt/jdk1.6.0_22/bin/java
80392   /usr/libexec/mysqld
311876  /opt/jdk1.6.0_22/bin/java
408780  Total

Що дає нижче значення для загального використовуваного свопу. Де залишився використаний swapspace? Це vmalloc () 'ed пам'ять всередині ядра? Щось ще? Як я можу це визначити?

Вихід пам’яті:

# cat /proc/meminfo 
MemTotal:       515324 kB
MemFree:          6696 kB
Buffers:          5084 kB
Cached:          28056 kB
SwapCached:     157512 kB
Active:         429372 kB
Inactive:        65068 kB
HighTotal:           0 kB
HighFree:            0 kB
LowTotal:       515324 kB
LowFree:          6696 kB
SwapTotal:      983032 kB
SwapFree:       478712 kB
Dirty:             100 kB
Writeback:           0 kB
AnonPages:      399456 kB
Mapped:           8792 kB
Slab:             7744 kB
PageTables:       1820 kB
NFS_Unstable:        0 kB
Bounce:              0 kB
CommitLimit:   1240692 kB
Committed_AS:  1743904 kB
VmallocTotal:   507896 kB
VmallocUsed:      3088 kB
VmallocChunk:   504288 kB
HugePages_Total:     0
HugePages_Free:      0
HugePages_Rsvd:      0
Hugepagesize:     4096 kB

Буфери та кеш-пам'ять включені, і вони не пов'язані з жодним процесом.
goldilocks

2
@goldilocks: ні, це у фізичній пам'яті. Крім того, вони не складаються.
ninj

Ви маєте рацію, я вважаю, що кешування матеріалів для заміни було б безглуздо. Однак я думаю, що замінені речі можуть залишатися там і відслідковуватися навіть після того, як процес, який належить йому, не працює, до тих пір, поки цей обмінний простір інакше не потрібен; це економить час пізніше, якщо процес завантажує ту саму сторінку, а потім цю сторінку потрібно знову замінити - вона все ще є в свопі. Google "swap cache" linux-tutorial.info/modules.php?name=MContent&pageid=314 Цей паралель із тим, як відбувається власне "кеш-кеш" (це зберігається в пам'яті від теперішніх процесів).
goldilocks

... сенс, лол, що «кешування речі в своп» не так безглуздо, так що він не отримує там заміни кеш RAM поза.
goldilocks

1
Чи не є відповідь лише тим, що ядро ​​може міняти місцями, і це не входить у вашу обробку? Зокрема, ядро ​​має цілу купу процесів "простору користувача" в даний час ... Просто врахування.
iain

Відповіді:


11

Різниця, яку ви спостерігаєте, насправді не пов’язана з тим, що місця обміну місцями не враховуються. "(Видалено)", яке ядро ​​іноді додає до /proc/*/exeпосилань, виводиться за допомогою readlinkі викликає помилки розбору в вашому скрипті awk, і ви фактично не рахуєте процесів, бінарні файли яких більше не містяться у вашій сукупності.

Деякі ядра додають слово "(видалено)" для /proc/*/exeпозначення цілей, коли оригінального виконуваного файлу для цього процесу вже немає.

Причина, по якій ваша команда відображає менше загальної, через це. Вихід readlinkна таких посиланнях буде чимось на кшталт "/ path / to / bin (видалено)", що спричиняє помилку розбору, awkколи вихід заміщається назад у рядок (це не любить круглі дужки та пробіли). Наприклад, зробіть це:

for a in /proc/*/exe ; do readlink $a ; done | grep deleted

І ви побачите кілька записів із доданим "(видаленим)". Якщо ви подивилися на використання свопів для цих записів, їх загальна сума відповідатиме розбіжності, яке ви бачите, оскільки отримані awkпомилки не дозволяють обчислити їх загальну суму та включити до остаточної суми.

Якщо ви запускаєте оригінальну команду, не перенаправляючи stderr нікуди, ви, мабуть, помітите кілька помилок "постійної рядкової послідовності". Ці помилки є результатом вищезазначеного, і ви не повинні були їх ігнорувати.

Ігноруючи інші потенційні вдосконалення вашої початкової команди, ви можете змінити її, видаливши "(видалено)", як це (примітка |awk '{print $1}'додана до readlinkвиводу):

for proc in /proc/*; \
  do cat $proc/smaps 2>/dev/null | awk '/Swap/{swap+=$2}END{print swap "\t'`readlink $proc/exe|awk '{print $1}' `'" }'; \
done | sort -n | awk '{total+=$1}/[0-9]/;END{print total "\tTotal"}'

Це використання awkдля виправлення результату readlinkможе порушитися, якщо ім'я містить пробіли - ви можете використовувати sedбудь-який інший спосіб, який ви бажаєте.

Інформація про бонус

До речі, ви могли просто скористатися smem -t. У стовпці "Зміна" відображається те, що ви хочете.

Щодо обчислення його самостійно, ви також можете отримати цю інформацію більш безпосередньо з VmSwapполя в /proc/*/status(smaps вимагає деякої підтримки ядра і не завжди доступна), і уникати необхідності перенаправляти помилки, використовуючи правильну схему імен файлів, що дозволяє уникнути помилки для початку:

for proc in /proc/[0-9]*; do \
  awk '/VmSwap/ { print $2 "\t'`readlink $proc/exe | awk '{ print $1 }'`'" }' $proc/status; \
done | sort -n | awk '{ total += $1 ; print $0 } END { print total "\tTotal" }'

Якщо ви не маєте потребу в довічним і може мати справу з просто мати ім'я процесу, ви можете отримати все від status:

for a in /proc/*/status ; do \
  awk '/VmSwap|Name/ { printf $2 " " } END { print "" }' $a ; \
done | awk '{ total+=$2 ; print $0 } END { print "Total " total }'

І нарешті, якщо вистачає лише PID-кодів, ви можете зробити це все за допомогою awk:

awk '/VmSwap/ { total += $2; print $2 "\t" FILENAME } END { print total "\tTotal" }' /proc/*/status

Примітка:

Тепер це не означає, що відмінностей між freeі smem(останній такий же, як і у вашого сценарію). Є багато (див., Наприклад, https://www.google.com/search?q=smem+free , що на першій сторінці має більш ніж достатньо результатів, щоб відповісти на ваші запитання щодо використання пам'яті). Але без належного тесту не можна вирішити вашу конкретну ситуацію.


5

Swap також використовується tmpfs, якщо ядро ​​потребує більше вільного оперативної пам’яті або просто тому, що воно деякий час не використовується… тому будь-яке використання tmpfs може споживати своп.


1
Чому потік? Це абсолютно правильно.
jlliagre
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.