В Linux, как мне узнать, какой процесс больше использует пространство подкачки?
В Linux, как мне узнать, какой процесс больше использует пространство подкачки?
Ответы:
Запустите сверху, затем нажмите OpEnter. Теперь процессы должны быть отсортированы по их использованию подкачки.
Вот обновление, так как мой оригинальный ответ не дает точного ответа на проблему, как указано в комментариях. Из htop FAQ :
Невозможно получить точный размер используемого пространства подкачки процесса. Top подделывает эту информацию, делая SWAP = VIRT - RES, но это не очень хорошая метрика, потому что другие вещи, такие как видеопамять, тоже учитываются в VIRT (например: top говорит, что мой процесс X использует 81M подкачки, но также сообщает, что моя система в целом использует только 2M подкачки. Поэтому я не буду добавлять аналогичный столбец подкачки в htop, потому что я не знаю надежного способа получить эту информацию (на самом деле, я не думаю, что это возможно получить точное число, из-за общих страниц).
Лучший сценарий, который я нашел, находится на этой странице: http://northernmost.org/blog/find-out-what-is-using-your-swap/
Вот один из вариантов скрипта и без рута:
#!/bin/bash
# Get current swap usage for all running processes
# Erik Ljungstrom 27/05/2011
# Modified by Mikko Rantalainen 2012-08-09
# Pipe the output to "sort -nk3" to get sorted output
# Modified by Marc Methot 2014-09-18
# removed the need for sudo
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"
Overall swap used: 260672 KB, пока бесплатные шоу, 738932как используется ...
for file in /proc/*/status ; do awk '/Tgid|VmSwap|Name/{printf $2 " " $3}END{ print ""}' $file; done | grep kB | sort -k 3 -nдля Debian / RH 6x +, Arch, Ubuntu (RH 5x имеет VmSize) ( источник ). Как и @dgunchev, он дает гораздо меньше общего свопа, чем free. @Tensibai не работает на Arch; в вашем awk может чего-то не хватать
top: northernmost.org/blog/swap-usage-5-years-later
Вот еще один вариант скрипта, но он предназначен для получения более читабельного вывода (вам нужно запустить его как root, чтобы получить точные результаты):
#!/bin/bash
# find-out-what-is-using-your-swap.sh
# -- Get current swap usage for all running processes
# --
# -- rev.0.3, 2012-09-03, Jan Smid - alignment and intendation, sorting
# -- rev.0.2, 2012-08-09, Mikko Rantalainen - pipe the output to "sort -nk3" to get sorted output
# -- rev.0.1, 2011-05-27, Erik Ljungstrom - initial version
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}/";
argsвместо commв psкоманде , так как у меня есть много процессов , с тем же именем , но с разными аргументами (связка питон gunicorn процессов). ps -p $PID -o args --no-headers
grep VmSwap $DIR/status 2>/dev/null | awk '{ print $2 }'можно упростить какawk ' /VmSwap/ { print $2 }'
Я заметил, что эта ветка довольно старая, но если вы случайно наткнулись на нее, как я только что сделал, другой ответ: используйте smem.
Вот ссылка, которая расскажет вам, как установить его и как его использовать:
http://www.cyberciti.biz/faq/linux-which-process-is-using-swap/
Не совсем понятно, хотите ли вы найти процесс, у которого было выгружено большинство страниц, или процесс, который вызвал замену большинства страниц.
Для первого вы можете запустить topи сделать заказ путем свопинга (нажмите «Op»), для последнего вы можете запустить vmstatи искать ненулевые записи для «так».
Команда top также содержит поле для отображения количества сбоев страниц для процесса. Процесс с максимальным количеством сбоев страниц будет процессом, который обменивается больше всего. Для длительно работающих демонов может случиться так, что они вначале сталкиваются с большим количеством сбоев страниц, и в дальнейшем это число не увеличивается. Таким образом, мы должны наблюдать, увеличивается ли количество ошибок на странице.
Еще один вариант сценария, позволяющий избежать цикла в оболочке:
#!/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
}'
Стандартное использование состоит в том, script.shчтобы получить использование для каждой программы в случайном порядке (вплоть до того, как awkхранит ее хеши) или script.sh 1отсортировать вывод по pid.
Надеюсь, я прокомментировал код достаточно, чтобы рассказать, что он делает.
bashкаталоги расширяются отсортированным способом (лексическим, а не числовым). Случайный порядок сводится к тому, как awkхранить свои массивы (хеш-таблицу) и как for p in pnameих извлекать.
/proc/1/statusследует из того, /proc/1992/statusчто /код ascii выше кода ascii 9. Это также дает внешний вид и случайный порядок). Я согласен с хеш-таблицей awk Я взял ярлык здесь. Не стесняйтесь редактировать ответ, чтобы сохранить атрибуцию в истории редактирования.
/proc/1/statusне будет следовать /proc/1992/statusв локали C, где порядок основан на значении байта. Это происходит в вашей локали (или в моей en_GB.UTF-8системе GNU), потому /что в алгоритме сортировки в первом случае игнорируется (и sсортируется после 9). Сравните printf '/proc/%s/status\n' 1 1992 | LC_ALL=en_GB.UTF-8 sortс printf '/proc/%s/status\n' 1 1992 | LC_ALL=C sort. В других локалях Cпорядок сортировки обычно не основан на значении байта.
Поскольку topили htopмогут быть не установлены в небольших системах, просмотр /procвсегда возможен.
Даже в небольших системах вы найдете shell...
Это точно так же , чем lolotux сценарий , но без какой - либо вилки grep, awkили ps. Это намного быстрее!
И, как удар один из самых бедных оболочка Что касается производительности, была проделана небольшая работа, чтобы этот скрипт хорошо работал под тир, BusyBoxи некоторые другие. Затем ( благодаря Стефану Шазеласу ) снова стать намного быстрее!
#!/bin/sh
# Get current swap usage for all running processes
# Felix Hauri 2016-08-05
# Rewritted without fork. Inspired by first stuff from
# Erik Ljungstrom 27/05/2011
# Modified by Mikko Rantalainen 2012-08-09
# Pipe the output to "sort -nk3" to get sorted output
# Modified by Marc Methot 2014-09-18
# removed the need for sudo
OVERALL=0
rifs=`printf ': \t'`
for FILE in /proc/[0-9]*/status ;do
SUM=0
while IFS="$rifs" read FIELD VALUE ;do
case $FIELD in
Pid ) PID=$VALUE ;;
Name ) PROGNAME="$VALUE" ;;
VmSwap ) SUM=$((SUM=${VALUE% *})) ;;
esac
done <$FILE
[ $SUM -gt 0 ] &&
printf "PID: %9d swapped: %11d KB (%s)\n" $PID $SUM "$PROGNAME"
OVERALL=$((OVERALL+SUM))
done
printf "Total swapped memory: %14u KB\n" $OVERALL
Не забудьте двойную кавычку "$PROGNAME"! Смотрите комментарий Стефана Шазеля :
read FIELD PROGNAME < <(
perl -ne 'BEGIN{$0="/*/*/../../*/*"} print if /^Name/' /proc/self/status
)
echo $FIELD "$PROGNAME"
Не пытайтесь echo $PROGNAMEбез двойной кавычки на разумной системе, и будьте готовы убить текущую оболочку раньше!
Поскольку это становится не таким простым сценарием, настало время написать специальный инструмент, используя более эффективный язык.
#!/usr/bin/perl -w
use strict;
use Getopt::Std;
my ($tot,$mtot)=(0,0);
my %procs;
my %opts;
getopt('', \%opts);
sub sortres {
return $a <=> $b if $opts{'p'};
return $procs{$a}->{'cmd'} cmp $procs{$b}->{'cmd'} if $opts{'c'};
return $procs{$a}->{'mswap'} <=> $procs{$b}->{'mswap'} if $opts{'m'};
return $procs{$a}->{'swap'} <=> $procs{$b}->{'swap'};
};
opendir my $dh,"/proc";
for my $pid (grep {/^\d+$/} readdir $dh) {
if (open my $fh,"</proc/$pid/status") {
my ($sum,$nam)=(0,"");
while (<$fh>) {
$sum+=$1 if /^VmSwap:\s+(\d+)\s/;
$nam=$1 if /^Name:\s+(\S+)/;
}
if ($sum) {
$tot+=$sum;
$procs{$pid}->{'swap'}=$sum;
$procs{$pid}->{'cmd'}=$nam;
close $fh;
if (open my $fh,"</proc/$pid/smaps") {
$sum=0;
while (<$fh>) {
$sum+=$1 if /^Swap:\s+(\d+)\s/;
};
};
$mtot+=$sum;
$procs{$pid}->{'mswap'}=$sum;
} else { close $fh; };
};
};
map {
printf "PID: %9d swapped: %11d (%11d) KB (%s)\n",
$_, $procs{$_}->{'swap'}, $procs{$_}->{'mswap'}, $procs{$_}->{'cmd'};
} sort sortres keys %procs;
printf "Total swapped memory: %14u (%11u) KB\n", $tot,$mtot;
может бежать с одним из
-c sort by command name
-p sort by pid
-m sort by swap values
by default, output is sorted by status's vmsize
:, обратной косой черты, подстановочных знаков или управляющих символов.
[1-9]ранее *для подсчета только пронумерованных путей (нет self, ни thread-self)
NameЗапись в /proc/*/statusкодирует некоторые из этих значений байтов. Попробуйте, например perl -ne 'BEGIN{$0="\n\t\\"} print if /^Name/' /proc/self/status. Поскольку он настолько короткий, ущерб, который может быть нанесен такими вещами, perl -ne 'BEGIN{$0="/*/*/../../*/*"} print if /^Name/' /proc/self/statusограничен, если вы забудете процитировать свои переменные.
Я адаптировал другой сценарий в Интернете для этой длинной строки:
{ 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 ; }
Который я тогда бросаю в cronjob и перенаправляю вывод в файл журнала. Информация здесь та же, что и при накоплении Swap:записей в файле smaps, но если вы хотите быть уверены, вы можете использовать:
{ date;for m in /proc/*/smaps;do
awk '/^Swap/ {s+=$2} END { if (s) print FILENAME,s }' $m 2>/dev/null;
done | tr -dc ' [0-9]\n' |sort -k 1n; }
Вывод этой версии в двух столбцах: pid, сумма обмена. В вышеприведенной версии trполосы не числовые компоненты. В обоих случаях выходные данные сортируются численно по pid.
Я полагаю, что вы могли бы получить хорошее предположение, запустив topи ища активные процессы, использующие много памяти. Делать это программно сложнее - просто посмотрите на бесконечные споры об эвристике убийцы Linux OOM.
Подкачка является функцией наличия большего количества памяти в активном использовании, чем установлено, поэтому обычно трудно обвинить это в одном процессе. Если это постоянная проблема, лучшим решением будет установка дополнительной памяти или внесение других системных изменений.
Дает итоги и проценты за процесс с использованием свопа
smem -t -p
Источник: https://www.cyberciti.biz/faq/linux-which-process-is-using-swap/
Я не знаю ни одного прямого ответа о том, как точно определить, какой процесс использует пространство подкачки, однако эта ссылка может оказаться полезной . Еще один хороший здесь
Кроме того, используйте хороший инструмент, такой как htop, чтобы увидеть, какие процессы используют много памяти и сколько общего объема подкачки используется.
iotopэто очень полезный инструмент. Он дает оперативную статистику ввода / вывода и использования свопа для процесса / потока. По умолчанию он показывает для потока, но вы можете сделать, iotop -Pчтобы получить информацию о процессе. Это не доступно по умолчанию. Возможно, вам придется установить через rpm / apt.
Вот версия, которая выводит то же самое, что и скрипт @loolotux, но намного быстрее (хотя и менее читабелен). Этот цикл занимает около 10 секунд на моей машине, моя версия занимает 0,019 с, что имело значение для меня, потому что я хотел превратить его в страницу CGI.
join -t / -1 3 -2 3 \
<(grep VmSwap /proc/*/status |egrep -v '/proc/self|thread-self' | sort -k3,3 --field-separator=/ ) \
<(grep -H '' --binary-files=text /proc/*/cmdline |tr '\0' ' '|cut -c 1-200|egrep -v '/proc/self|/thread-self'|sort -k3,3 --field-separator=/ ) \
| cut -d/ -f1,4,7- \
| sed 's/status//; s/cmdline//' \
| sort -h -k3,3 --field-separator=:\
| tee >(awk -F: '{s+=$3} END {printf "\nTotal Swap Usage = %.0f kB\n",s}') /dev/null
Начиная с исправления ядра 2015 года, которое добавляет SwapPss( https://lore.kernel.org/patchwork/patch/570506/ ), можно наконец получить пропорциональный счет подкачки, что означает, что если процесс поменялся много раз, а затем разветвился, оба разветвленных процесса будет сообщено о свопе на 50% каждый. И если любой из них затем разветвляется, то каждый процесс считается 33% переставленных страниц, поэтому, если вы посчитаете все эти операции подкачки вместе, вы получите реальное использование подкачки вместо значения, умноженного на количество процессов.
Коротко:
(cd /proc; for pid in [0-9]*; do printf "%5s %6s %s\n" "$pid" "$(awk 'BEGIN{sum=0} /SwapPss:/{sum+=$2} END{print sum}' $pid/smaps)" "$(cat $pid/comm)"; done | sort -k2n,2 -k1n,1)
Первый столбец pid, второй столбец - использование свопа в КиБ, а остальная часть строки - выполнение команды. Идентичные числа свопа отсортированы по pid.
Выше могут испускать линии, такие как
awk: cmd. line:1: fatal: cannot open file `15407/smaps' for reading (No such file or directory)
это просто означает, что процесс с pid 15407 закончился между его отображением в списке /proc/и чтением smapsфайла процесса . Если это важно для вас, просто добавьте 2>/dev/nullв конец. Обратите внимание, что вы потенциально можете потерять любую другую возможную диагностику.
В примере с реальным миром это меняет другие инструменты, сообщающие о ~ 40 МБ использования подкачки для каждого дочернего элемента apache, работающего на одном сервере, на фактическое использование между 7-3630 КБ, реально используемыми для каждого дочернего элемента.