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


当前回答

我不知道如何确切地找到哪个进程正在使用交换空间的直接答案,但是,这个链接可能会有帮助。另一个好例子在这里

另外,使用像htop这样的好工具来查看哪些进程使用了大量内存,以及总体上使用了多少交换空间。

其他回答

这是脚本的另一个变体,但意味着提供更可读的输出(你需要以根用户身份运行这个脚本才能得到准确的结果):

#!/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命令还包含一个字段,用于显示进程的页面错误数量。页面错误最多的进程是交换次数最多的进程。 对于长时间运行的守护进程,可能会在开始时产生大量的页面错误,并且这个数字在以后不会增加。所以我们需要观察页面故障是否在增加。

自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,第二列是KiB中的交换使用情况,其余一行是正在执行的命令。相同的交换计数按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即可。请注意,您可能还会丢失任何其他可能的诊断。

在现实世界的示例案例中,这改变了其他报告在一台服务器上运行的每个apache子服务器使用约40 MB交换空间的工具,而每个子服务器实际使用7-3630 KB交换空间。

我不知道如何确切地找到哪个进程正在使用交换空间的直接答案,但是,这个链接可能会有帮助。另一个好例子在这里

另外,使用像htop这样的好工具来查看哪些进程使用了大量内存,以及总体上使用了多少交换空间。

我认为,您可以通过运行top并查找使用大量内存的活动进程来得到一个很好的猜测。通过编程实现这一点比较困难——只要看看关于Linux OOM杀手启发式的无休止的争论就知道了。

交换是一种活动使用的内存比安装的内存多的功能,因此通常很难将其归咎于单个进程。如果这是一个持续的问题,最好的解决方案是安装更多的内存,或进行其他系统更改。