Find out what is using your swap

Have you ever logged in to a server, ran `free`, seen that a bit of swap is used and wondered what’s in there? It’s usually not very indicative of anything, or even overly helpful knowing what’s in there, mostly it’s a curiosity thing.

Either way, starting from kernel 2.6.16, we can find out using smaps which can be found in the proc filesystem. I’ve written a simple bash script which prints out all running processes and their swap usage.
It’s quick and dirty, but does the job and can easily be modified to work on any info exposed in /proc/$PID/smaps
If I find the time and inspiration, I might tidy it up and extend it a bit to cover some more alternatives. The output is in kilobytes.

#!/bin/bash
# Get current swap usage for all running processes
# Erik Ljungstrom 27/05/2011
SUM=0
OVERALL=0
for DIR in `find /proc/ -maxdepth 1 -type d | egrep "^/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
echo "PID=$PID - Swap used: $SUM - ($PROGNAME )"
let OVERALL=$OVERALL+$SUM
SUM=0

done
echo "Overall swap used: $OVERALL"

This will need to be ran as root for it to be able to gather accurate numbers. It will still work even if you don’t, but it will report 0 for any processes not owned by your user.
Needless to say, it’s Linux only. The output is ordered alphabetically according to your locale (which admittedly isn’t a great thing since we’re dealing with numbers), but you can easily apply your standard shell magic to the output. For instance, to find the process with most swap used, just run the script like so:

$ ./getswap.sh | sort -n -k 5
Don’t want to see stuff that’s not using swap at all?
$ ./getswap.sh | egrep -v "Swap used: 0" |sort -n -k 5

… and so on and so forth

This entry was posted in Sundry sysadmin. Bookmark the permalink.

40 Responses to Find out what is using your swap

  1. Craig Hancock says:

    WOW I have been looking for this on LINUX for atleast 2 years.

    Thank you for your efforts.
    -
    Craig Hancock

  2. jalal hajigholamali says:

    Very nice article….
    Thanks a lot

  3. lolotux says:

    Many Tks for this very nice script !

  4. kerneljack says:

    really handy, thanks!

  5. Here is a bit different solution:

    #!/bin/bash
    # Identify the processes that use swap
    # Marian Marinov 30.Aug.2011
    total_swap=0
    cd /proc
    for pid in [0-9]*; do
    cmdline=$(cat /proc/$pid/cmdline 2>/dev/null|tr ” ‘ ‘)
    pid_swap=$(awk ‘BEGIN{total=0}/Swap/{total+=$2}END{print total}’ /proc/$pid/smaps 2>/dev/null)
    if [ "$pid_swap" != '' ] && [ "$pid_swap" -gt 0 ]; then
    echo “PID=$pid – Swap used: $pid_swap Kb – ($cmdline)”
    let total_swap+=$pid_swap
    fi
    done
    echo “Total swap: $total_swap Kb”

  6. Also if you change the above awk command to this one:
    awk ‘/VmSwap/{print $2}’ /proc/$pid/status

    You can get almost the same information on any linux.

  7. a says:

    ls -d /proc/*/smaps|cut -f 3 -d ‘/’|grep -E ‘^[0-9]+$’

  8. Thanks for the comments! Glad it’s of some use!

    Also thanks Marian, your solution with showing the name of the program is a good idea as well.

  9. Pingback: Help! Linux ate my ram!

  10. jezzellutin says:

    This script may be very helpful but, is there anyone who can explain me why when i run “free” it says that there is some swap used… And the script here just tells that there is no process that used swap …
    (?)

  11. kiran says:

    may be because you are not running with root

  12. jmccreery says:

    @kiran Nope… I’m getting the exact same thing, and I’m _definitely_ root… /proc/meminfo confirms that there is exactly 116kb of swap used, with no smaps info. A quick peek at google shows that that ’116kb’ (specifically) is a popular number to see in a free memory swap utilization report. Anyone know why?

  13. Unconvinced says:

    I’m also not convinced this is working, or at least it’s not doing what I thought it would do. The script — run as root — reports 205,312 Kb of swap used. But free -k reports 2,254,524 Kb used. What would explain a discrepancy of over 2 GB?!

  14. It could be a case of how shared pages are reported.

    Try entering top, press f, then press p, then press return, then press F, then press p, then press return, add up the numbers in the “SWAP” column.
    They should be similar to the ones printed by the above script.

    If I run ‘free -k’, it shows 1180 KB of swap used, but top and my script reports 48. So it could be non-reclaimed and/or shared pages etc. which free reports.

  15. michael says:

    like this, but even though I run it as root it still only shows size 0 (on Fedora 15)

  16. Jon says:

    Thanks very much! This is a very useful script – have been trying to debug high latency on a server for weeks now and this may just have hit the nail on the head :)

    Whenever I come across a script like this I realise just how little I actually understand about Linux!

  17. Jonathan Bayer says:

    On Aug. 30, Marian Marinov posted a nice script. However, the “tr” part of it seems to have been corrupted by the site, because it shows the following:

    cmdline=$(cat /proc/$pid/cmdline 2>/dev/null|tr ” ‘ ‘)

    and the syntax for tr is not correct. Any idea what he’s trying to do here? The only thing I can figure is that he’s trying to replace any nulls with spaces, in which case the syntax should be:

    cmdline=$(cat /proc/$pid/cmdline 2>/dev/null|tr ” ” )

  18. Tom Adriaansen says:

    About the | tr ” ” .
    I think its for getting the parameters from the cmdline straight.
    by example (syslogd-m0-r-x) has to be (syslogd -m 0 -r -x)
    So translate octal 0 “” to space ” ”
    cmdline=$(cat /proc/$pid/cmdline 2>/dev/null | tr “” ” “)

  19. Tom Adriaansen says:

    Octal 0 = octal zero and is writen as backslash zero. \

  20. dolanor says:

    Thanks for this script. I was wondering how to get this information.

    I’ve made a “VERY” little change in your script by using the -regex option of find instead of | grep “whatever”

    I’ve put it on gitorious. I will use it to store every nice scripts like that that are always useful but sometimes get lost in the web because of blog closing etc
    https://gitorious.org/dolanormisc/scripts/blobs/master/getswapused

  21. Peter says:

    About the “tr”-problem: this is just because of the quotes are changed to quotes used in books or similar. Just change them to “real” single or double quotes and it will work.

  22. Pingback: Sultans of Swap « Dancing with UNIX

  23. Pingback: Quora

  24. Pingback: Some notes on Linux memory usage | Upon 2020

  25. user says:

    Thank you, very useful script

  26. Mad Clown says:

    Thx 4 ur script :]

  27. Andreas says:

    What requirements have to be met to get it to work? RHEL5 is not working, Debian Squeeze is working (at least I got something … which doesn’t sum up to swap but I get at least an idea what is using how much swap space).

  28. John says:

    Thanks for the script, I’ll make sure to put it to good use.

    I’ve already made one edit to it, to only print lines of procs using greater then 0 Swap:

    15 done
    16 if [[ ${SUM} > 0 ]]
    17 then
    18 echo “PID=$PID – Swap used: $SUM – ($PROGNAME )”
    19 fi
    20 let OVERALL=$OVERALL+$SUM

    Lines 15,18, and 20 are from your original script just you can see where it fit in. Minor edit but it trims down the output to what I really need :)

  29. Pingback: How to find which process is using swap under linux | LPE

  30. Olystretch says:

    One line solution:

    Just replace with the actual PID of the application you want to check the swap usage of.

    SWAP=`sudo grep Swap /proc//smaps 2> /dev/null | awk '{ print $2 }' | paste -sd+ | bc`; echo $SWAP KB

  31. Olystretch says:

    OK, so I guess I shouldn’t have used html brackets. Let me try again.
    Lets pretend that you only want to check the swap usage of a certain application. After getting the PID from top (or another method that suits you best) Just replace {PID} with the actual PID of the application you want to check the swap usage of.

    SWAP=`sudo grep Swap /proc/{PID}/smaps 2> /dev/null | awk '{ print $2 }' | paste -sd+ | bc`; echo $SWAP KB

    Bam!

  32. Pingback: Useful Shell Script – Swap Usage | Utoxin's Random Insanity

  33. Collin says:

    Nice script! Thanks a lot.

    I’m using this for my output
    echo -e “Usage: $SUM\tPID: $PID\t($PROGNAME)”

  34. Danny says:

    thanks a lot.

    you fixed my headache.

  35. Pingback: Memory management / Swap file issue - Astaro User Bulletin Board

  36. jokea says:

    Not working properly on my machine (Centos-5.4, kernel 2.6.30):

    top shows:
    Swap: 8385920k total, 5792k used,

    this script shows:
    PID=1 swapped 64 KB (init)
    PID=1121 swapped 308 KB (udevd)
    PID=3184 swapped 36 KB (syslogd)
    PID=3187 swapped 36 KB (klogd)
    PID=3201 swapped 56 KB (irqbalance)
    PID=3441 swapped 212 KB (xinetd)
    PID=3484 swapped 200 KB (crond)
    PID=3545 swapped 68 KB (mingetty)
    PID=3546 swapped 72 KB (mingetty)
    PID=3547 swapped 68 KB (mingetty)
    PID=3548 swapped 72 KB (mingetty)
    PID=3549 swapped 68 KB (mingetty)
    PID=3550 swapped 68 KB (mingetty)
    PID=23581 swapped 460 KB (sshd)
    PID=32138 swapped 448 KB (puppetd)
    Overall swap used: 2236 KB

    /proc/meminfo:
    MemTotal: 49057196 kB
    MemFree: 7005608 kB
    Buffers: 271792 kB
    Cached: 11774812 kB
    SwapCached: 4960 kB
    Active: 27844908 kB
    Inactive: 13563020 kB
    Active(anon): 27310004 kB
    Inactive(anon): 2051608 kB
    Active(file): 534904 kB
    Inactive(file): 11511412 kB
    Unevictable: 0 kB
    Mlocked: 0 kB
    SwapTotal: 8385920 kB
    SwapFree: 8380128 kB
    Dirty: 76 kB
    Writeback: 0 kB
    AnonPages: 29360012 kB
    Mapped: 6280 kB
    Slab: 447288 kB
    SReclaimable: 418336 kB
    SUnreclaim: 28952 kB
    PageTables: 62708 kB
    NFS_Unstable: 0 kB
    Bounce: 0 kB
    WritebackTmp: 0 kB
    CommitLimit: 32914516 kB
    Committed_AS: 30380912 kB
    VmallocTotal: 34359738367 kB
    VmallocUsed: 383644 kB
    VmallocChunk: 34359341539 kB
    HugePages_Total: 0
    HugePages_Free: 0
    HugePages_Rsvd: 0
    HugePages_Surp: 0
    Hugepagesize: 2048 kB
    DirectMap4k: 5604 kB
    DirectMap2M: 2078720 kB
    DirectMap1G: 48234496 kB

  37. Doctor Gage says:

    There is a handy package called smem which can output this info via ‘smem -s swap’.

    http://www.selenic.com/smem/

    Debian/Ubuntu hint to not make it install X11 on your server:
    apt-get –no-install-recommends install smem

  38. jokea says:

    @Gage, still not accurate:
    # /tmp/smem -u
    User Count Swap USS PSS RSS
    root 27 4848 46264 47451 55028
    nobody 1 0 1529496 1529727 1530368
    work 4 0 29089640 29089884 29092312

    # top
    Swap: 8385920k total, 6828k used,

    2GB swap are missing in smem’s output.

  39. jokea says:

    same amount as the script:
    Overall swap used: 4848

Comments are closed.