Какие процессы заняли 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» завершена.