Skip to content

Instantly share code, notes, and snippets.

@gwarser
Forked from chriseckhardt/swap-cop.sh
Last active August 30, 2021 12:07
Show Gist options
  • Save gwarser/edb18e59cd2c264474d9df92d8831202 to your computer and use it in GitHub Desktop.
Save gwarser/edb18e59cd2c264474d9df92d8831202 to your computer and use it in GitHub Desktop.
Simple script that displays processes' vm swap usage
#!/bin/bash
# Get current swap usage for all running processes
# NOTE: MUST BE RUN AS ROOT (checks /proc/)
# Erik Ljungstrom 27/05/2011
# Modified by Mikko Rantalainen 2012-08-09
# Modified by Brandon Johnson 2013-07-30
# Pipe the output to "sort -nk3" to get sorted output
# set PID to echo full command path, mysql procs only showed "mysql", which was useless on services with multiple daemons running.
# Also added MB/GB feature for the purposes of using this tool with grep -e "MB" -e "GB"
# VmSwap amount of swap used by anonymous private data (shmem swap
# usage is not included)
#
# “Swap” shows how much would-be-anonymous memory is also used, but out
# on swap.
#
# For shmem mappings, “Swap” includes also the size of the mapped (and
# not replaced by copy-on-write) part of the underlying shmem object out
# on swap. “SwapPss” shows proportional swap share of this mapping. Unlike
# “Swap”, this does not take into account swapped out page of underlying
# shmem objects.
#
# https://www.kernel.org/doc/html/latest/filesystems/proc.html
SUM=0
SUM2=0
OVERALL=0
OVERALL2=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 cmd --no-headers`
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
for SWAP in `grep VmSwap $DIR/status 2>/dev/null | awk '{ print $2 }'`
do
let SUM2=$SUM2+$SWAP
done
if (( $SUM > 0 )); then
echo "PID=$PID swapped $SUM KB (smaps/Swap) or $SUM2 KB (status/VmSwap) ($PROGNAME)"
fi
let OVERALL=$OVERALL+$SUM
let OVERALL2=$OVERALL2+$SUM2
SUM=0
SUM2=0
done
echo "Overall Swap used: $[$OVERALL/1048576] (GB), $[$OVERALL/1024] (MB), $OVERALL KB"
echo "Overall VmSwap used: $[$OVERALL2/1048576] (GB), $[$OVERALL2/1024] (MB), $OVERALL2 KB"
@mikkorantalainen
Copy link

mikkorantalainen commented Aug 30, 2021

Here's another version using SwapPss: (proportional) field which results in same totals as VmSwap method above. The difference between Swap and SwapPss is that if the same swapped block is shared by N programs then Swap will report that memory N times in total (once for each process) whereas SwapPss will report memory / N as the swapped amount for each process.

The field Swap is the correct one to use if you want to know how much data must be transferred from swap to the process memory space if all swapped data is needed again.

The use of proportional data results in correct total and better describes the current swap usage per process. However, because it's computed on the fly, it doesn't mean that system can actually free any memory if a process with high SwapPss process is killed. In that case, the resulting processes just appear to increase SwapPss usage instead because the divider N gets smaller.

#!/bin/bash 
# Get current swap usage for all running processes (proportional usage which makes the total amount correct)
# Erik Ljungstrom 27/05/2011
# Modified by Mikko Rantalainen 2021-08-30
# Pipe the output to "sort -n -k 3" to get sorted output
# Note: if you run this as non-root, the result will be for your own processes only!
# Note: even if you run this as root, the total will usually be less than your swap usage because neither shmem nor tmpfs usage is included here!
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 SwapPss: $DIR/smaps 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"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment