【问题标题】:How to find out which processes are using swap space in Linux?如何找出 Linux 中哪些进程正在使用交换空间?
【发布时间】:2010-10-03 13:22:48
【问题描述】:

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

【问题讨论】:

  • 您接受的答案是错误的。考虑改成lolotux的答案,其实是正确的。
  • @jterrace 是正确的,我没有像顶部 SWAP 列中的值总和那么多的交换空间。
  • iotop 是一个非常有用的命令,它将显示每个进程/线程的 io 和交换使用情况的实时统计信息
  • @jterrace,考虑说明谁的接受的当天回答是错误的。六年后,我们其他人不知道您是指大卫霍尔姆的答案(目前已接受的答案)还是其他答案。 (好吧,我看到你还说大卫霍尔姆的答案是错误的,作为对他答案的评论......所以我猜你可能是指他的。)
  • smem -s swap -r 是一个不错的选择。 related answer 当前位于两个自定义脚本答案下方。

标签: linux memory swap


【解决方案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"

【讨论】:

  • 有趣的是,我得到了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)(source)。与@dgunchev 一样,它确实提供的总交换量比free 少得多。 @Tensibai 不适用于 Arch;你的 awk 可能缺少一些东西。
  • 请看我的no fork version这个脚本!
  • 作者有一个后续帖子,关于如何使用topnorthernmost.org/blog/swap-usage-5-years-later
【解决方案2】:

运行top,然后按OpEnter。现在应该按照它们的交换使用情况对进程进行排序。

这是一个更新,因为我的原始答案没有提供对 cme​​ts 中指出的问题的确切答案。来自htop FAQ

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

【讨论】:

  • 从文档中,顶部的 SWAP 列似乎只是显示了如果整个进程被换出,则需要多少交换,而不是当前实际交换了多少进程。根据我在短暂搜索后可以看出的情况,目前无法确定每个进程中有多少被换出。因此,htop 的作者拒绝放入这样的专栏(我确实看到了 CNSWAP 和 NSWAP 专栏,但它们似乎在我的机器上没有做任何事情):htop.sourceforge.net/index.php?page=faq
  • @yukondude 是对的,顶部的 SWAP 列只是 VIRT - RES,这些信息在这种情况下是无用的。没有补偿,例如映射视频 RAM 的共享内存。此外,进程可能还没有引用所有内存。在这种情况下,操作系统不需要将完整的二进制文件从磁盘读取到内存中,因此 RES 的值不包括这部分内存。
  • 如果可以的话,我会更赞成这个。这是在救我的培根!
  • 谢天谢地,这就是 @jterrace 的 cmets :) (尽管您必须阅读它们:S...不确定 atrain 指的是什么,我希望它是 yukondude)
  • 关于评论不再起作用:似乎最新版本的 top 不再将“O”设置为选择排序字段的键。使用时?键可以看到实际的程序名称和版本,procps-ng 是最新版本。这是 Debian、Fedora 和 openSUSE 的一个分支:gitorious.org/procps。如果您仍想对 SWAP 列进行排序:使用“f”键查看字段,使用箭头键转到 SWAP 并使用“s”设置排序,然后使用“q”。跨度>
【解决方案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
  • 旁注grep VmSwap $DIR/status 2>/dev/null | awk '{ print $2 }'可以简化为awk ' /VmSwap/ { print $2 }'
【解决方案4】:

使用smem

smem -s swap -r

这是一个告诉您如何安装和如何使用它的链接:http://www.cyberciti.biz/faq/linux-which-process-is-using-swap/

【讨论】:

  • 这个不错。这是该文章的改编版本,以显示按交换使用排序并添加了 PID 的 proc: $ for file in /proc/*/status ;执行 awk '/^Pid|VmSwap|Name/{printf $2 " " $3}END{ print ""}' $file;完成 |排序 -k 3 -n -r |少
  • 您应该 glob /proc/[1-9]*/status 排除几个特殊的 /proc 条目,并且可以将排序参数组合为 -rnk3
【解决方案5】:

不清楚您的意思是要查找换出页面最多的进程还是导致换出页面最多的进程。

对于第一个,您可以运行 top 并通过交换排序(按“Op”),对于后者,您可以运行 vmstat 并查找“so”的非零条目。

【讨论】:

    【解决方案6】:

    另一个避免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 对输出进行排序。

    我希望我对代码的注释足以说明它的作用。

    【讨论】:

    • 请注意,bash 以排序方式(词汇,而非数字)扩展目录。随机顺序取决于awk 如何存储其数组(哈希表)以及for p in pname 如何检索它们。
    • @StephaneChazelas 好吧,这甚至不是词汇,这是一种 ascii 代码排序(因为 /proc/1/status/proc/1992/status 之后,并且 / 在 9 个 ascii 代码之上有一个 ascii 代码。这给出了“随机顺序”的外观和感觉。我同意 awk 哈希表,我在这里采取了捷径。随意编辑答案以将属性保留在编辑历史记录中。
    • /proc/1/status 在 C 语言环境中不会出现在 /proc/1992/status 之后,其中顺序基于字节值。它在您的语言环境中(或在 GNU 系统上的我的en_GB.UTF-8 中),因为/ 在排序算法的第一个实例中被忽略(并且s9 之后排序)。比较 printf '/proc/%s/status\n' 1 1992 | LC_ALL=en_GB.UTF-8 sortprintf '/proc/%s/status\n' 1 1992 | LC_ALL=C sort。在C 以外的语言环境中,排序顺序通常基于字节值。
    • @StephaneChazelas 很好,虽然没有关于语言环境。再次随意编辑以添加精度,因此学分将归您所有(至少在历史编辑中)。
    • 完成。这个答案比这里投票最多的答案要好得多。它确实值得更多的支持。 Why is using a shell loop to process text considered bad practice? 讨论了这里的那个和其他答案,这就是把我带到这里的原因。
    【解决方案7】:

    还有两个变种:

    因为tophtop 无法安装在小型系统上,所以始终可以浏览/proc

    即使在小型系统上,您也会发现 shell...

    变体! (不仅是 bash)

    这与lolotux script 完全相同,但没有对grepawkps 的任何分叉。这要快得多!

    由于 是性能最差的 之一,因此我们做了一些工作以确保此脚本在 和其他一些环境下运行良好。然后,(thanks to Stéphane 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
    for FILE in /proc/[0-9]*/status ;do
        SUM=0
        while read FIELD VALUE;do
            case $FIELD in
                Pid )    PID=$VALUE         ;;
                Name )   PROGNAME="$VALUE"  ;;
                VmSwap ) SUM=${VALUE%% *} ; break ;;
            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éphane Chazelas's comment:

    read FIELD PROGNAME < <(
        perl -ne 'BEGIN{$0="/*/*/../../*/*"} print if /^Name/' /proc/self/status
    )
    echo $FIELD "$PROGNAME"
    

    不要尝试echo $PROGNAME在明智的系统上没有双引号,并准备好之前杀死当前的shell!

    还有一个 版本

    随着这变得不是那么简单脚本,是时候使用更高效的语言编写专用工具了。

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

    【讨论】:

    • 它假定进程名称不包含空格、制表符、:、反斜杠、通配符或控制字符。
    • @StephaneChazelas 谢谢!我在* 之前添加了[1-9],用于仅计算编号路径(没有self,也没有thread-self
    • 语法已知,但进程名称未知。至少quote your variables。 (无论如何,你的脚本比 loloxux 差很多)。
    • Linux 上的进程名称可以包含除 0 以外的任何字节值,但长度限制为 15 个字节。 /proc/*/status 中的 Name 条目对其中的一些字节值进行编码。例如perl -ne 'BEGIN{$0="\n\t\\"} print if /^Name/' /proc/self/status。因为它很短,所以当您忘记引用变量时,使用 perl -ne 'BEGIN{$0="/*/*/../../*/*"} print if /^Name/' /proc/self/status 之类的东西可以造成的损害是有限的。
    • 这(至少是我刚刚尝试过的 perl 版本)比其他答案要快得多。
    【解决方案8】:

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

    【讨论】:

      【解决方案9】:

      我在网上改编了一个不同的脚本来适应这个冗长的单行:

       { 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,swap amount。在上述版本中,tr 去除了非数字组件。在这两种情况下,输出都按 pid 进行数字排序。

      【讨论】:

      • 这很好,但第一个按 pid 升序排序(sort -n)。更好的用法是按交换使用量降序排序(列表前面使用最多的)。为了得到它,将“sort -n”更改为“sort -n -k 3 -r”
      【解决方案10】:

      给出使用交换的进程的总数和百分比

      smem -t -p
      

      来源:https://www.cyberciti.biz/faq/linux-which-process-is-using-swap/

      【讨论】:

      • 哦,我不知道smem可以做到这一点,谢谢! FTR,我修改了一个我通常使用的命令看起来像这样smem -kc "name user pid vss pss rss swap",所以现在我可以看到最后一列中使用的交换量。
      【解决方案11】:

      在 MacOSX 上,您也可以运行 top 命令,但需要输入“o”,然后输入“vsize”,然后再输入。

      【讨论】:

        【解决方案12】:

        自从 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&gt;/dev/null。请注意,您也可能会丢失任何其他可能的诊断信息。

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

        【讨论】:

          【解决方案13】:

          我想你可以通过运行top 并寻找使用大量内存的活动进程来得到一个很好的猜测。以编程方式执行此操作更难——只要看看关于 Linux OOM 杀手启发式的无休止辩论。

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

          【讨论】:

            【解决方案14】:

            这是一个与@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
            

            【讨论】:

              【解决方案15】:

              这是我的一个班轮:

              cat /proc/*/status | grep -E 'VmSwap:|Name:' | grep VmSwap -B1 | cut -d':' -f2 | grep -v '\-\-' | grep -o -E '[a-zA-Z0-9]+.*$' | cut -d' ' -f1 | xargs -n2 echo | sort -k2 -n
              

              这一行的步骤是:

              • 获取/proc/process/status中所有进程的所有数据
              • 为每个字段选择 VmSwap 和 Name
              • 删除没有 VmSwap 字段的进程
              • 删除字段的名称(VmSwap: 和 Name:)
              • 删除上一步添加的带有 -- 的行
              • 删除行首的空格
              • 删除每个进程名的第二部分和交换使用编号后的“kB”
              • 获取名称和编号(进程名称和交换使用)并将它们放在一行中,一个接一个
              • 按交换使用情况对行进行排序

              【讨论】:

                【解决方案16】:

                我不知道任何直接的答案是如何准确地找到正在使用交换空间的进程,但是,这个链接可能是helpful。另一个不错的是over here

                另外,使用 htop 之类的好工具来查看哪些进程正在使用大量内存以及总共使用了多少交换空间。

                【讨论】:

                  【解决方案17】:

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

                  【讨论】:

                    【解决方案18】:

                    您可以使用Procpath(作者在此处)来简化从/proc/$PID/status 解析VmSwap

                    $ procpath record -f stat,cmdline,status -r 1 -d db.sqlite
                    $ sqlite3 -column db.sqlite \
                      'SELECT status_name, status_vmswap FROM record ORDER BY status_vmswap DESC LIMIT 5'
                    Web Content  192136       
                    okular       186872       
                    thunderbird  183692       
                    Web Content  143404       
                    MainThread   86300
                    

                    您还可以像这样随着时间的推移绘制VmSwap 感兴趣的过程。在这里,我记录了我的 Firefox 进程树,同时打开了几十个选项卡,并启动了一个需要大量内存的应用程序以尝试使其交换(这对 Firefox 来说并不令人信服,但你的里程可能会有所不同)。

                    $ procpath record -f stat,cmdline,status -i 1 -d db2.sqlite \
                      '$..children[?(@.stat.pid == 6029)]'
                    # interrupt by Ctrl+C
                    $ procpath plot -d db2.sqlite -q cpu --custom-value-expr status_vmswap \
                      --title "CPU usage, % vs Swap, kB"
                    

                    【讨论】:

                      【解决方案19】:

                      @lolotux 的答案相同,但输出排序:

                      printf 'Computing swap usage...\n';
                      swap_usages="$(
                          SUM=0
                          OVERALL=0
                      
                          for DIR in `find /proc/ -maxdepth 1 -type d -regex "^/proc/[0-9]+"`
                          do
                              PID="$(printf '%s' "$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
                                  printf "$SUM KB ($PROGNAME) swapped PID=$PID\\n"
                              fi
                              let OVERALL=$OVERALL+$SUM
                              SUM=0
                              break
                          done
                          printf '9999999999 Overall swap used: %s KB\n' "$OVERALL"
                      )"
                      
                      printf '%s' "$swap_usages" | sort -nk1
                      

                      示例输出:

                      Computing swap usage...
                      2064 KB (systemd) swapped PID=1
                      59620 KB (xfdesktop) swapped PID=21405
                      64484 KB (nemo) swapped PID=763627
                      66740 KB (teamviewerd) swapped PID=1618
                      68244 KB (flameshot) swapped PID=84209
                      763136 KB (plugin_host) swapped PID=1881345
                      1412480 KB (java) swapped PID=43402
                      3864548 KB (sublime_text) swapped PID=1881327
                      9999999999 Overall swap used: 2064 KB
                      

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 1970-01-01
                        • 2022-11-24
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2013-03-08
                        • 1970-01-01
                        相关资源
                        最近更新 更多