当前位置:  开发笔记 > 编程语言 > 正文

如何找出Linux中使用交换空间的进程?

如何解决《如何找出Linux中使用交换空间的进程?》经验,为你挑选了8个好方法。

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



1> 小智..:

我找到的最好的脚本是在这个页面上: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"


相同的输出速度快十倍:`for file in/proc/*/status; do awk'/ Tgid | VmSwap |姓名/ {printf $ 2""$ 3} END {print""}'$ file; 完成| grep kB | 排序-k 3 -n`用于Debian/RH 6x +,Arch,Ubuntu(RH 5x有`VmSize`)([来源](http://www.vincentliefooghe.net/content/linux-gestion-la-ram-et -du交换)).就像@dgunchev一样,它的总交换量比"免费"少得多.@Tensibai不适用于Arch; 你的awk可能缺少一些东西.
有趣的是,我得到`使用的总体交换:260672 KB`,而免费显示`738932`使用...
作者有一篇后续文章,介绍如何使用“ top”操作:http://northernmost.org/blog/swap-usage-5-years-later/

2> David Holm..:

运行顶部然后按OpEnter.现在,流程应按其交换使用情况进行排序.

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

无法获得进程的已使用交换空间的确切大小.Top通过制作SWAP = VIRT-RES来伪造这些信息,但这不是一个好的指标,因为其他东西,如视频内存也计入VIRT(例如:top说我的X进程使用81M的交换,但它也报告我的系统整体上只使用了2M的交换.因此,我不会在htop中添加类似的Swap列,因为我不知道获取此信息的可靠方法(实际上,我认为不可能得到这些信息)一个确切的数字,因为共享页面).


从文档中,顶部的SWAP列似乎只显示了整个流程被换出时需要多少交换,而不是目前实际交换了多少流程.从简短的搜索后我可以看出,目前无法确定每个进程的换出量.htop的作者因为这个而拒绝输入这样的专栏(我确实看到了CNSWAP和NSWAP专栏,但他们似乎没有在我的机器上做任何事情):http://htop.sourceforge.net/index.php ?页=常见问题解答
为什么这是公认的答案?这是完全错误的.
关于评论不再起作用:似乎更新版本的top不再将'O'设置为选择排序字段的关键.使用时?键,你可以看到实际的程序名称和版本,procps-ng是最新版本.这是Debian,Fedora和openSUSE的一个分支:https://gitorious.org/procps.如果您仍希望对SWAP列进行排序:使用"f"键查看字段,使用箭头键转到SWAP并使用"s"设置排序,然后使用"q".
@yukondude是对的,顶部的SWAP列只是VIRT-RES,这个信息在这种情况下是无用的.例如,映射视频RAM的共享存储器没有补偿.此过程还没有引用所有内存.在这种情况下,操作系统不必将完整的二进制文件从磁盘读入内存,因此RES的值不包括这部分内存.

3> 小智..:

这是脚本的另一个变体,但是意味着提供更可读的输出(您需要以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}/";


非常好的剧本.它提供了与lolotux相同的信息,但是以更好的可读方式.
我唯一改变的是在`ps`命令中使用`args`而不是`comm`,因为我有很多具有相同名称但不同参数的进程(一堆python gunicorn进程).即:`ps -p $ PID -o args --no-headers`

4> Ronny Vinden..:

如果您想要找到大多数页面被换出或处理导致大多数页面被换出的进程,那么这一点并不完全清楚.

对于第一个,您可以top通过交换运行和订购(按'Op'),对于后者,您可以运行vmstat并查找'so'的非零条目.



5> Tom..:

我注意到这个线程相当陈旧,但如果你偶然发现它,就像我刚才那样,另一个答案是:使用smem.

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

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



6> 小智..:

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



7> Tensibai..:

避免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对输出进行排序.

我希望我已经对代码进行了评论,足以说明它的作用.


完成.这个答案比这里投票最多的答案要好得多.它确实值得更多的赞成.这里和其他答案在[为什么使用shell循环处理文本被认为是不好的做法?](http://unix.stackexchange.com/a/301525)讨论了这就是我带到这里的原因.

8> F. Hauri..:

还有两个变体:

一个壳变种!(不仅限于bash)

这正是比相同lolotux剧本,但没有任何叉grepawkps。这要快得多!

由于bash是性能最差的shell之一,因此做了一些工作来确保该脚本在dash,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,") {
            $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,") {
                    $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

推荐阅读
惬听风吟jyy_802
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有