A "nearly out of swap"-alarm¹ during on call duty led me to quickly assemble a one-liner to grab a list of PIDs and the amount of memory swapped out from /proc/[pid]/smaps. That one-liner later got a bit polishing from my colleague H. to look like this:

for x in $(ps -eo pid h); do s=/proc/${x}/smaps; [ -e ${s} ] && awk -vp=${x} 'BEGIN { sum=0 } /Swap:/ { sum+=$2 } END { if (sum!=0) print sum " PID " p}' ${s}; done | sort -rg

After I shared this one with some friends V. came up with a faster version (and properly formatted output :), that relies on the "VMSwap" value in /proc/[pid]/status. Since the one-liner above has to add up one "Swap" value per memory segment it's obvious why it's very slow on systems with many processes and a lot of memory.

awk 'BEGIN{printf "%-7s %-16s %s (KB)\n", "PID","COMM","VMSWAP"} {
if($1 == "Name:"){n=$2}
if($1 == "Pid:"){p=$2}
if($1 == "VmSwap:" && $2 != "0"){printf "%-7s %-16s %s\n", p,n,$2 | "sort -nrk3"}
}' /proc/*/status

Drawback of this second version is that it relies on the "VmSwap" value which is only part of Linux 2.6.34 and later. It also ended up in the 2.6.32 based kernel of RHEL 6, so this one should work from RHEL 6 and Debian/wheezy onwards. The first version also works on RHEL 5 and Debian/squeeze since both have a (default) kernel with "CONFIG_PROC_PAGE_MONITOR" enabled, which is what you need to enable /proc/[pid]/smaps.

Update: C.R. pointed out via mail that there is a versatile Python script smem. It's available in Debian and at least EPEL 6 and 7. Thanks for the hint.

¹ The usefulness of swap and why there is no automatic ressource assignment check and bookkeeping, based on calculations around things like the JVM -Xmx settings and other input, is a story on its own. There is room for improvement. A CMDB (Chapter 10.7) would be a starting point.