What and why is my swap space used under linux

Solution 1:

Even if there's no application demands on your memory, Linux will swap out unused portions of processes "in advance" of actually needing to so that it can free that memory immediately when the time comes. You can adjust the tendency to do this by adjusting vm.swappiness (/proc/sys/vm/swappiness) per the instructions here.

As for seeing what is swapped, you're theoretically able to tell from the output of top (by subtracting the virtual and resident memory columns, or using the swap column that does the same for you) but my system has 0 swap used and an apache2 process with 248m "Virtual Image", of which 9376k is supposedly "resident", leaving 239m "swapped". I'm not sure if there's an actual way to identify which specific processes or parts of processes are actually in the swap file.

Solution 2:

Here's a script to show you the swap used by process on your Linux system.

Credit to the original author: Erik Ljungstrom 27/05/2011.

Modified by me to increase usefulness and friendliness. HTH.

#!/bin/bash
#
# Get current swap usage for running processes
# Original: Erik Ljungstrom 27/05/2011
# Modifications by ariel:
#   - Sort by swap usage
#   - Auto run as root if not root
#   - ~2x speedup by using procfs directly instead of ps
#   - include full command line in output
#   - make output more concise/clearer
#   - better variable names
#

# Need root to look at all processes details
case `whoami` in
    'root') : ;;
    *) exec sudo $0 ;;
esac

(
    PROC_SWAP=0
    TOTAL_SWAP=0

    for DIR in `find /proc/ -maxdepth 1 -type d | grep "^/proc/[0-9]"` ; do
        PID=`echo $DIR | cut -d / -f 3`
        CMDLINE=`cat /proc/$PID/cmdline 2>/dev/null | tr '\000' ' '`
        for SWAP in `grep Swap $DIR/smaps 2>/dev/null | awk '{ print $2 }'`
        do
            let PROC_SWAP=$PROC_SWAP+$SWAP
        done
        if [ $PROC_SWAP == 0 ]; then
            # Skip processes with no swap usage
            continue
        fi
        echo "$PROC_SWAP        [$PID] $CMDLINE"
        let TOTAL_SWAP=$TOTAL_SWAP+$PROC_SWAP
        PROC_SWAP=0
    done
    echo "$TOTAL_SWAP   Total Swap Used"
) | sort -n