How to find out which processes are using swap space in Linux?

后端 未结 18 1874
终归单人心
终归单人心 2020-11-27 09:11

Under Linux, how do I find out which process is using the swap space more?

相关标签:
18条回答
  • 2020-11-27 09:28

    You can use Procpath (author here), to simplify parsing of VmSwap from /proc/$PID/status.

    $ 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
    

    You can also plot VmSwap of processes of interest over time like this. Here I'm recording my Firefox process tree while opening a couple tens of tabs along with statrting a memory-hungry application to try to cause it to swap (which wasn't convincing for Firefox, but your kilometrage may vary).

    $ 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"
    

    0 讨论(0)
  • 2020-11-27 09:29

    I don't know of any direct answer as how to find exactly what process is using the swap space, however, this link may be helpful. Another good one is over here

    Also, use a good tool like htop to see which processes are using a lot of memory and how much swap overall is being used.

    0 讨论(0)
  • 2020-11-27 09:30

    Another script variant avoiding the loop in 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
      }'
    

    Standard usage is script.sh to get the usage per program with random order (down to how awk stores its hashes) or script.sh 1 to sort the output by pid.

    I hope I've commented the code enough to tell what it does.

    0 讨论(0)
  • 2020-11-27 09:31

    I did notice this thread is rather old, but if you happen to stumble upon it, as I just did, another answer is: use smem.

    Here is a link which tells you both how to install it and how to use it:

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

    0 讨论(0)
  • 2020-11-27 09:38

    Here's another variant of the script, but meant to give more readable output (you need to run this as root to get exact results):

    #!/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}/";
    
    0 讨论(0)
  • 2020-11-27 09:38

    The same answer as @lolotux, but with sorted output:

    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
    

    Example output:

    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
    
    0 讨论(0)
提交回复
热议问题