题
在Linux下,我怎么找出哪些进程正在使用的交换空间吗?
解决方案
运行顶然后按 0 P 输入。现在进程应可以通过交换使用排序。
下面是一个更新的我原来的答复并没有这个问题提供一个确切的答案在评论中指出。从 HTOP常见问题解答:
这是不可能得到的的用于交换空间的确切大小 处理。顶级假货通过使SWAP = VIRT此信息 - RES,但 这不是一个很好的指标,因为作为显存等其他的东西 在VIRT计数以及(例如:上面说我的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"
下面是脚本的另一种变体,但为了给更多可读的输出(你需要运行这个作为根得到精确的结果):
#!/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}/";
如果你的意思是你要找到谁已经大部分页面换出或者进程的进程谁造成大多数页面被换出它不是完全清楚。
有关第一你可能运行通过交换(按“运算”)top
和顺序,后者可以运行vmstat
并查找非零项关于“这样”。
我也注意到这个线程是比较旧的,但如果你碰巧在它绊倒,因为我只是做了,另一个答案是:使用SMEM
下面是它告诉你一个链接二者如何安装它,以及如何使用它:
在顶部命令还包含一个字段,用于显示页面错误的数目的处理。最大页面错误的过程会是它最交换的过程。 对于长时间运行的后台程序可能是,他们无需花费大量的页面错误的开头和数量不会以后增加。因此,我们需要观察有无缺页中断增加。
另一脚本变体避免壳循环:
#!/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)的
这正是比 lolotux脚本相同,但没有任何叉grep
,awk
或ps
。这是快了很多!
和作为的bash 是最贫穷的一个外壳问题,一些工作做是为了确保该脚本将在破折号问题,<一类=“标签后的” href =“/问题/标记/ busybox的”标题=相对=“标签”> busybox的和其他一些“显示标记‘busybox的’问题”。然后,(感谢斯特凡Chazelas )更快再次成为了很多!
#!/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"
!请参见斯特凡Chazelas的评论:
read FIELD PROGNAME < <(
perl -ne 'BEGIN{$0="/*/*/../../*/*"} print if /^Name/' /proc/self/status
)
echo $FIELD "$PROGNAME"
不要试图echo $PROGNAME
不懂事系统上双引号,并准备好之前杀了当前shell!
和一个 perl的版本
由于这成为不是那么简单的脚本,时间正在添加通过使用更高效的语言写的专用工具。
#!/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
在MacOSX的,运行top命令,以及,但需要键入“○”,然后“VSIZE”,然后输入。
我适于在网络上不同的脚本,以这个长单行:
{ 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和输出重定向到日志文件。这里的信息是一样的积累在smaps文件Swap:
项,但如果你要确定,你可以使用:
{ 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杀手启发了无休止的争论。
交换是在具有多个存储器的功能的活性使用比被安装,因此它通常是很难归咎于一个单一的过程。如果它是一个长期存在的问题,最好的解决方案是安装更多的内存,或进行其他系统性变化。
iotop
是一种非常有用的工具。它提供的I / O和每个进程/线程交换使用实时统计数据。默认情况下,它显示了每个线程,但你可以做iotop -P
每个进程的信息获得。这不是默认情况下可用。可能必须通过rpm安装/公寓。
下面是其输出与由所述@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