如何找出哪些进程在Linux交换?

在Linux下,如何找出哪个进程使用交换空间更多?

运行顶部,然后按O p Enter键 。 现在,进程应该按照交换使用情况进行sorting。

这是一个更新,因为我的原始答案没有提供评论中指出的问题的确切答案。 从htop FAQ :

不可能获得进程使用的交换空间的确切大小。 通过制作SWAP = VIRT – RES来欺骗这个信息,但这不是一个好的指标,因为其他的东西,比如video内存也在VIRT上计数(例如:顶部说我的X进程使用了​​81M的swap,但是它也是报告我的系统整体只使用了2M的swap,所以我不会在htop中添加一个类似的Swap列,因为我不知道获取这些信息的可靠方法(实际上,我不认为这是可能的确切的数字,因为共享页面)。

我发现的最好的脚本是在这个页面上: http : //northernmost.org/blog/find-out-what-is-using-your-swap/

这里有一个脚本的变体,不需要root:

#!/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" 

这是脚本的另一个变体,但是为了给出更多可读的输出(你需要以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}/"; 

如果您的意思是您想要查找大部分页面被换出的stream程或处理导致大部分页面被换出的stream程,并不十分清楚。

对于第一个你可以运行top和顺序交换(按“操作”),对于后者,你可以运行vmstat并寻找非“零”的条目。

我注意到这个线程是相当老的,但是如果碰巧碰到它,就像我刚才那样,另一个答案是:使用smem。

这是一个链接,告诉你如何安装它,以及如何使用它:

http://www.cyberciti.biz/faq/linux-which-process-is-using-swap/

top命令还包含一个字段,用于显示进程的页面错误数量。 具有最大页面错误的进程将是交换最多的进程。 对于长时间运行的守护进程来说,可能是他们在开始时会产生大量的页面错误,并且以后不会再增加。 所以我们需要观察页面错误是否在增加。

另一个避免shell中循环的脚本变体:

 #!/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对输出进行sorting。

我希望我已经评论了足够的代码来说明它的作用。

然而,一个壳变种! (不只是bash)

这和lolotux脚本完全一样,但没有grepawkps任何分支。 这是更快!

由于bash是性能最差的shell之一,为了确保这个脚本能够在破折号 , busybox等等下运行,做了一些小小的工作。 然后,( 感谢StéphaneChazelas )再次变得更快了!

 #!/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" ! 见StéphaneChazelas的评论 :

 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 smap values by default, output is sorted by status's vmsize 

我猜你可以通过运行top寻找一个很好的猜测,并用大量的内存寻找活动的进程。 以这种方式进行编程更加困难—只要看看关于Linux OOM杀手级启发式的无尽争论。

交换是具有更多内存在活动使用的function比安装,所以通常很难将其归咎于一个单一的过程。 如果这是一个持续的问题,最好的解决办法是安装更多的内存,或进行其他系统更改。

我不知道如何直接find正确的交换空间,但是这个链接可能会有所帮助 。 另一个好的是在这里

另外,使用像htop这样的好工具来查看哪些进程正在使用大量的内存,以及整体使用的交换量。

在MacOSX上,你也运行top命令,但是需要input“o”,然后“vsize”然后回车。

iotop是一个非常有用的工具。 它提供了每个进程/线程的I / O和交换使用情况的实时统计信息。 默认情况下,它显示每个线程,但你可以做iotop -P来获得每个进程的信息。 这在默认情况下不可用。 您可能需要通过rpm / apt进行安装。

我在网上修改了一个不同的脚本,

  { 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并把输出redirect到一个日志文件。 这里的信息与积累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,swap数量。 在上面的版本中, tr剥离了非数字组件。 在这两种情况下,输出都以pid数字sorting。