14

On my system i have some amount of swap used:

undefine@uml:~$ free
             total       used       free     shared    buffers     cached
Mem:      16109684   15848264     261420     633496      48668    6096984
-/+ buffers/cache:    9702612    6407072
Swap:     15622140        604   15621536

How to check what is in swap?

I try to check it via processes, but for every pid on system VmSwap is 0:

undefine@uml:~$ awk '/VmSwap/ {print $2}' /proc/*/status |uniq
0

What else can be in swap? I thought about tmpfs - but i reread all files on tmpfs-es - and it doesn't flush swap size.


8

smem is the standard tool for this. It's clean and simple.

On a Debian based system, install it via package manager:

 sudo apt-get install smem

A sample (clipped) output from my system:

$ smem -s swap -t -k -n
  PID User     Command                         Swap      USS      PSS      RSS 
  831 1000     /bin/bash                          0     3.8M     3.8M     5.5M 
 3931 1000     bash /usr/bin/sage -c noteb   276.0K     4.0K    20.0K     1.2M 
17201 1000     /usr/bin/dbus-launch --exit   284.0K     4.0K     8.0K   500.0K 
17282 1000     /usr/bin/mate-settings-daem   372.0K    11.0M    11.7M    21.8M 
17284 1000     marco                         432.0K    16.7M    18.1M    29.5M 
17053 1000     mate-session                  952.0K     3.3M     3.5M     9.2M 
 3972 1000     python /usr/lib/sagemath/sr     2.7M   101.8M   102.1M   104.3M 
-------------------------------------------------------------------------------
  141 1                                        5.2M     3.9G     4.0G     4.5G 
  • 6
    But does it return anything other than the value shown in the VmSwap line in /proc/PID/status? The question isn't asking for a prettier display, it's asking what could be in swap other than process data. – Gilles May 23 '15 at 0:40
  • 1
    smem doesn't give me nothing more usefull than greping proc: undefine@uml:~$ sudo smem -c swap |uniq -c 1 Swap 227 0 – undefine May 24 '15 at 11:22
2

I only started looking into it yesterday for my needs, below is what I've found so far:

SWAP_USED = Used_by_Processes + SwapCached + Part_of_Tmpfs + something_else

Short story:

Used_by_Processes – data that has been swapped out from memory completely.

SwapCached – data that has been swapped to disk, but still remains in memory.

Part_of_Tmpfs – some portion of tmpfs data.

Long story:

Used_by_Processes – there are many instructions published on how to mis-calculate this one ;) E.g. if we sum up all VmSwap entries from /proc/*/status or Swap entries from /proc/*/smaps - we will get an overestimate (shared swapped pages could get counted more than once). If we don't run it from root user or our OS - the underestimate will be silently returned. I don't have a proper way of identifying shared pages, but splashing of same 'maps' gives much better approximation than other approaches: (note that cat below is not useless and actually needs a 2>/dev/null)

[root@a:~]# cat /proc/*/status|awk '      /^VmSwap/{           s+=$2       }END{print s}'
32048
[root@a:~]# cat /proc/*/smaps|awk '         /^Swap/{           s+=$2       }END{print s}'
32048
[root@a:~]# cat /proc/*/smaps|awk '/-/{r=$0}/^Swap/{if(R[r]!=1)s+=$2;R[r]=1}END{print s}'
14940
[root@a:~]# free -k|grep -e Swap -e used
             total       used       free     shared    buffers     cached
Swap:      8388600      15508    8373092

SwapCached – this one is straightforward and can be cleanly extracted from /proc/meminfo. Some people wouldn't expect this to be counted as "used" swap, since a duplicate (non-dirty) copy of same page in both RAM and Swap can be freed on either side quite instantly (in case if demand comes) thus making one of the copies "freed".

Part_of_Tmpfs – the bright side is that when all Your tmpfs data is many-days-untouched and swappiness is non-zero - it's quite likely that entire tmpfs is swapped-out (and vice-versa for recently-used data). The downside is I've found no API to reliably calculate the threshold or percentage of how much of it IS swapped, though if there's enough RAM - we can copy entire tmpfs data into /dev/null and thus get some clue of how much of it WAS swapped.

Common mistakes made during calculation of tmpfs size are - assuming that /dev/shm is the only tmpfs configured or trying to do it by recursive per-file scanning (not only implementations tend to omit hidden files or do it from non-root, but it also un-swaps some pages during traversing). Much easier way is to use good old df.

something_else – see the "diff 385 MB" below, needs a dive into kernel sources. See my script:

#!/bin/bash
TMPFS=`df -kP           |awk '          /^tmpfs/{          s+=$3       }END{print int( s/1024)}'`
PROCS=`cat /proc/*/smaps|awk '/-/{r=$0} /^Swap/{if(R[r]!=1)s+=$2;R[r]=1}END{print int( s/1024)}'`
SCACH=`cat /proc/meminfo|awk '          /^SwapCached/                      {print int($2/1024)}'`
TOTAL=`free -k          |awk '          /^Swap/                            {print int($3/1024)}'`
echo  -e " df $TMPFS\t    smaps $PROCS \tSwapCache $SCACH\t| $TOTAL\tswap | diff $[TOTAL-TMPFS-PROCS-SCACH]\tMB"

and the output from different boxes:

xa002:   df 0       smaps 271   SwapCache 3858  | 4120  swap | diff -9  MB
sg003:   df 0       smaps 234   SwapCache 3876  | 4111  swap | diff 1   MB
sg001:   df 0       smaps 245   SwapCache 3845  | 4093  swap | diff 3   MB
sg002:   df 0       smaps 244   SwapCache 3843  | 4091  swap | diff 4   MB
dm001:   df 2       smaps 971   SwapCache 728   | 1707  swap | diff 6   MB
hm012:   df 270     smaps 161   SwapCache 29    | 454   swap | diff -6  MB
hm003:   df 274     smaps 142   SwapCache 27    | 440   swap | diff -3  MB
hm006:   df 262     smaps 150   SwapCache 29    | 437   swap | diff -4  MB
hm002:   df 265     smaps 120   SwapCache 28    | 412   swap | diff -1  MB
hm009:   df 258     smaps 124   SwapCache 33    | 410   swap | diff -5  MB
hm011:   df 262     smaps 118   SwapCache 28    | 406   swap | diff -2  MB
hm008:   df 245     smaps 122   SwapCache 32    | 396   swap | diff -3  MB
hm005:   df 247     smaps 120   SwapCache 33    | 396   swap | diff -4  MB
dp001:   df 0       smaps 0     SwapCache 0     | 386   swap | diff 386 MB
hm014:   df 184     smaps 134   SwapCache 34    | 343   swap | diff -9  MB
hm007:   df 0       smaps 132   SwapCache 32    | 158   swap | diff -6  MB
bm002:   df 0       smaps 121   SwapCache 25    | 141   swap | diff -5  MB
dm002:   df 2       smaps 70    SwapCache 71    | 139   swap | diff -4  MB
bm001:   df 3       smaps 102   SwapCache 28    | 131   swap | diff -2  MB
bm004:   df 0       smaps 98    SwapCache 29    | 126   swap | diff -1  MB
hm013:   df 0       smaps 100   SwapCache 30    | 124   swap | diff -6  MB
bm006:   df 0       smaps 103   SwapCache 15    | 122   swap | diff 4   MB
hm010:   df 0       smaps 102   SwapCache 24    | 122   swap | diff -4  MB
hm001:   df 0       smaps 101   SwapCache 25    | 121   swap | diff -5  MB
bm003:   df 0       smaps 98    SwapCache 15    | 107   swap | diff -6  MB
bm005:   df 0       smaps 70    SwapCache 17    | 85    swap | diff -2  MB
sg004:   df 0       smaps 72    SwapCache 14    | 83    swap | diff -3  MB
sg001:   df 0       smaps 41    SwapCache 33    | 78    swap | diff 4   MB
sg005:   df 0       smaps 59    SwapCache 20    | 75    swap | diff -4  MB
sg003:   df 0       smaps 58    SwapCache 18    | 72    swap | diff -4  MB
sg006:   df 0       smaps 56    SwapCache 13    | 65    swap | diff -4  MB
sg002:   df 0       smaps 54    SwapCache 12    | 64    swap | diff -2  MB
xa001:   df 0       smaps 56    SwapCache 5     | 55    swap | diff -6  MB

And a small experiment as the bonus:

[root@hm012:~]# df -h|grep -e '^Filesystem' -e '^tmpfs'
Filesystem            Size  Used Avail Use% Mounted on
tmpfs                  12G  271M   12G   3% /dev/shm
tmpfs                 8.0G   84K  8.0G   1% /tmp
[root@hm012:~]# ./get_swap.sh
 df 270     smaps 161   SwapCache 29    | 454   swap | diff -6  MB
[root@hm012:~]# rm -rf /dev/shm/*
[root@hm012:~]# df -h|grep -e '^Filesystem' -e '^tmpfs'
Filesystem            Size  Used Avail Use% Mounted on
tmpfs                  12G     0   12G   0% /dev/shm
tmpfs                 8.0G   84K  8.0G   1% /tmp
[root@hm012:~]# ./get_swap.sh
 df 0       smaps 161   SwapCache 29    | 185   swap | diff -5  MB

P.S. aside from the approximation mentioned above - there are other sources of error, like rounding of KB into MB, theoretical possibility of a mismatch between block-sizes of RAM and Swap, etc. I'm not sure it covers everything, but hoping this helps to some extent :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.