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
WOW I have been looking for this on LINUX for atleast 2 years.
Thank you for your efforts.
-
Craig Hancock
Very nice article….
Thanks a lot
Many Tks for this very nice script !
really handy, thanks!
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”
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.
ls -d /proc/*/smaps|cut -f 3 -d ‘/’|grep -E ‘^[0-9]+$’
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.
Pingback: Help! Linux ate my ram!
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 …
(?)
may be because you are not running with root
@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?
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?!
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.
like this, but even though I run it as root it still only shows size 0 (on Fedora 15)
Thx!
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!
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 ” ” )
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 “” ” “)
Octal 0 = octal zero and is writen as backslash zero. \
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
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.
Pingback: Sultans of Swap « Dancing with UNIX
Pingback: Quora
Pingback: Some notes on Linux memory usage | Upon 2020