Какие процессы заняли SWAP в Unix/Linux
Утилиты top/htop и free отображают общее количество свободной, занятой физической памяти, а так же SWAP на сервере. Как определить, какой процесс использует пространство подкачки в Unix/Linux?
Вы можете использовать любой из следующих методов (но имейте в виду, что из-за общих страниц, нет никакого надежного способа получить данную информацию):
- Используйте «/proc/meminfo» – Утилита, которая покажет общие сведения об RAM/SWAP. Данная статистика используется с утилитой «free», чтобы сообщить количество свободной и используемой памяти (как физической, так и swap) в системе, а также общей памяти и буферов используемых ядром. Вы также можете использовать free, vmstat и другие инструменты чтобы узнать ту же информацию.
- «/proc/${PID}/smaps», «/proc/${PID}/status» и «/proc/${PID}/stat» — Используя эти утилиты, чтобы найти информацию о памяти, страницах и swap-е используемых каждым процессом( зная PID процесса).
- Используя smem.
Какие процессы заняли SWAP в Unix/Linux
Можно добиться желаемого результата несколькими способами.
Находим идентификатор процесса (PID):
# pidof memcached
Альтернатива, использовать «pgrep» команду для поиска PID-а:
# pgrep memcached
И так, одна из команд выведет подобный результат:
79225
Чтобы увидеть сколько использует swap служба memcached можно следующим образом:
# cat /proc/79225/status | grep -E "VmSwap"
И так, я показал сколько используется swap-а по указанному процессу ( memcached), но это не совсем удобно т.к имеется и ряд других процессов которые могут или использует swap, по этому — я сейчас покажу как можно красиво использовать данные утилиты для проверки.
Введите следующую команду в терменале, чтобы увидеть использование свопа по каждому процессу:
# for file in /proc/*/status ; do awk '/VmSwap|Name/{printf $2 " " $3}END{ print ""}' $file; done
Небольшая оптимизация — используем сортировку и вывод частями:
for file in /proc/*/status ; do awk '/VmSwap|Name/{printf $2 " " $3}END{ print ""}' $file; done | sort -k 2 -n -r | less
Еще варианты….
{ date;for f in /proc/[0-9]*/status; do awk '{k[$1]=$2} END { if (k["VmSwap:"]) print k["Pid:"],k["Name:"],k["VmSwap:"];}' $f 2>/dev/null; done | sort -n ; }
Нашел небольшой bash скрипт:
# vim /usr/local/src/swap_processes_checker.sh
И прописываем в него:
#!/bin/bash # Get current swap usage for all running processes # Erik Ljungstrom 27/05/2011 SUM=0 OVERALL=0 for DIR in `find /proc/ -maxdepth 1 -type d | egrep "^/proc/[0-9]"` ; do PID=`echo $DIR | cut -d / -f 3` PROGNAME=`ps -p $PID -o comm --no-headers` for SWAP in `grep Swap $DIR/smaps 2>/dev/null| awk '{ print $2 }'` do let SUM=$SUM+$SWAP done echo "PID=$PID - Swap used: $SUM - ($PROGNAME )" let OVERALL=$OVERALL+$SUM SUM=0 done echo "Overall swap used: $OVERALL"
Запускайте его от суперпользователя для того, чтобы иметь возможность собрать точные цифры. Скрипт будет работать и от любого другого пользователя в системе, но если у него не поулчится получить доступ к процессу которые не принадлежат вашему пользователю, то он не сможет показать данные по процессам. Например, чтобы найти процесс с большим использованием свопа, просто запустите скрипт вот так:
$ sudo bash /usr/local/src/swap_processes_checker.sh | sort -n -k 5
Данные скрипт покажет все процессы которые используют или не используют SWAP, но можно убрать ненужно ( отображать только те процессы, которые имеют обращение к свапу):
$ sudo bash /usr/local/src/swap_processes_checker.sh| egrep -v "Swap used: 0" |sort -n -k 5
Выход будет в килобайтах.
Вот уже готовый, упрощенный скрипт:
#!/bin/bash SUM=0 OVERALL=0 for DIR in `find /proc/ -maxdepth 1 -type d -regex "^/proc/[0-9]+"` do PID=`echo $DIR | cut -d / -f 3` PROGNAME=`ps -p $PID -o comm --no-headers` for SWAP in `grep VmSwap $DIR/status 2>/dev/null | awk '{ print $2 }'` do let SUM=$SUM+$SWAP done if (( $SUM > 0 )); then echo "PID=$PID swapped $SUM KB ($PROGNAME)" fi let OVERALL=$OVERALL+$SUM SUM=0 done echo "Overall swap used: $OVERALL KB"
Хочу показать отличную вариацию данного скрипта ( на мой взгляд — одно из самых лучших):
#!/bin/bash SCRIPT_NAME=`basename $0`; SORT="kb"; # {pid|kB|name} as first parameter, [default: kb] [ "$1" != "" ] && { SORT="$1"; } [ ! -x `which mktemp` ] && { echo "ERROR: mktemp is not available!"; exit; } MKTEMP=`which mktemp`; TMP=`${MKTEMP} -d`; [ ! -d "${TMP}" ] && { echo "ERROR: unable to create temp dir!"; exit; } >${TMP}/${SCRIPT_NAME}.pid; >${TMP}/${SCRIPT_NAME}.kb; >${TMP}/${SCRIPT_NAME}.name; SUM=0; OVERALL=0; echo "${OVERALL}" > ${TMP}/${SCRIPT_NAME}.overal; for DIR in `find /proc/ -maxdepth 1 -type d -regex "^/proc/[0-9]+"`; do PID=`echo $DIR | cut -d / -f 3` PROGNAME=`ps -p $PID -o comm --no-headers` for SWAP in `grep Swap $DIR/smaps 2>/dev/null| awk '{ print $2 }'` do let SUM=$SUM+$SWAP done if (( $SUM > 0 )); then echo -n "."; echo -e "${PID}\t${SUM}\t${PROGNAME}" >> ${TMP}/${SCRIPT_NAME}.pid; echo -e "${SUM}\t${PID}\t${PROGNAME}" >> ${TMP}/${SCRIPT_NAME}.kb; echo -e "${PROGNAME}\t${SUM}\t${PID}" >> ${TMP}/${SCRIPT_NAME}.name; fi let OVERALL=$OVERALL+$SUM SUM=0 done echo "${OVERALL}" > ${TMP}/${SCRIPT_NAME}.overal; echo; echo "Overall swap used: ${OVERALL} kB"; echo "========================================"; case "${SORT}" in name ) echo -e "name\tkB\tpid"; echo "========================================"; cat ${TMP}/${SCRIPT_NAME}.name|sort -r; ;; kb ) echo -e "kB\tpid\tname"; echo "========================================"; cat ${TMP}/${SCRIPT_NAME}.kb|sort -rh; ;; pid | * ) echo -e "pid\tkB\tname"; echo "========================================"; cat ${TMP}/${SCRIPT_NAME}.pid|sort -rh; ;; esac rm -fR "${TMP}/";
Вот еще один вариант использования:
#!/bin/bash grep VmSwap /proc/[0-9]*/status | awk -F':' -v sort="$1" ' { split($1,pid,"/") # Split first field on / split($3,swp," ") # Split third field on space cmdlinefile = "/proc/"pid[3]"/cmdline" # Build the cmdline filepath getline pname[pid[3]] < cmdlinefile # Get the command line from pid swap[pid[3]] = sprintf("%6i %s",swp[1],swp[2]) # Store the swap used (with unit to avoid rebuilding at print) sum+=swp[1] # Sum the swap } END { OFS="\t" # Change the output separator to tabulation print "Pid","Swap used","Command line" # Print header if(sort) { getline max_pid < "/proc/sys/kernel/pid_max" for(p=1;p<=max_pid;p++) { if(p in pname) print p,swap[p],pname[p] # print the values } } else { for(p in pname) { # Loop over all pids found print p,swap[p],pname[p] # print the values } } print "Total swap used:",sum # print the sum }'
Они все работают и их можно использовать для своих нужд. А можно использовать утилиту smem. О ней можно прочитать тут:
Установка smem для проверки RAM/SWAP активности в Unix/Linux
А на этом, у меня все! Статья «Какие процессы заняли SWAP в Unix/Linux» завершена.