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


当前回答

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

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

其他回答

另一种在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对输出进行排序。

我希望我已经对代码进行了足够的注释,以说明它的功能。

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

与@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

我在网上改编了一个不同的脚本来写这句长单句:

 { 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数值排序的。

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

smem -t -p

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