3

I use my Linux box for a lot of computational work, and sometimes a particular computation eats a lot of RAM. When I'm done, I end up with a bunch of swap used and a bunch of free memory, and if I go about my business as usual, all the other processes on the machine will be a bit laggy until they get swapped back in. It seems like it would be nice if there were a command to quickly page everything back into RAM so that I could, say, run it and then get up and go use the restroom or something and when I get back everything would be fast again.

I found this question that suggests you can accomplish this (at least on Linux) with

sudo swapoff -a
sudo swapon -a

But when I try that, it takes forever - it's only freeing swap at a rate of 2-5 MB/sec, which is way less than it should be capable of, and hardly seems worth it. Is this normal? Is there a way to speed this process up so that it runs in "going to the restroom" time instead of "going out to lunch" time?

  • 1
    How can swapoff be that slow? – don_crissti Mar 31 '15 at 20:13
  • Are you using a swapfile rather than a partition? – teppic Apr 1 '15 at 0:36
  • @don_crissti guess I should search around more before I post. That looks like it explains things pretty well. – arcticmac Apr 2 '15 at 0:25
  • @teppic swapping to a partition not a file. Installed 'atop' for looking at this today; it lists the disk as 10-20% "busy" during the operation, while swapoff is using ~80% CPU. So I don't think it's primarily disk-bound. – arcticmac Apr 2 '15 at 0:27
  • @arcticmac which kernel are you using? I've never had this problem myself but it's hard to fill swap up in a genuine way (rather than just deliberately filling up memory). – teppic Apr 2 '15 at 0:46
2

I recently had the same problem, and created this to clean the swap out quickly:

#Single-proc function to core-dump swapped ranges > 1M to /dev/null
unswap(){ (awk -F'[ \t-]+' '/^[a-f0-9]*-[a-f0-9]* /{recent="0x"$1" 0x"$2}/Swap:/&&$2>1000{print recent}' /proc/$1/smaps | while read astart aend; do gdb --batch --pid $1 -ex "dump memory /dev/null $astart $aend" &>/dev/null; done&)2>/dev/null;};

#Loop to run unswap on the top 20 swap-consuming processes
grep VmSwap /proc/*/status 2>/dev/null | sort -nk2 | tail -n20 | cut -d/ -f3 | while read line; do unswap $line; done;

#Observe the number of core dumps currently running, along with free swap, over time. 
echo "Dumps Free(m)"; rcount=10; while [[ $rcount -gt 0 ]]; do rcount=$(ps fauxww | grep "dump memory" | grep -v grep | wc -l); echo "$rcount        $(free -m | awk '/Swap/{print $4}')"; sleep 1; done 

If this doesn't work in your specific environment, the process is as follows:

1. Get a list of the processes consuming the most swap.

In my case, I'm checking /proc/$pid/status, with the swap use in the VmSwap row.

# grep VmSwap /proc/*/status 2>/dev/null | sort -nk2 | tail -n5
/proc/22457/status:VmSwap:      3780 kB
/proc/22684/status:VmSwap:      4260 kB
/proc/7408/status:VmSwap:       4396 kB
/proc/31992/status:VmSwap:      9176 kB
/proc/2967/status:VmSwap:      60840 kB

2. For the high-swap procs, I find the memory address ranges which are contributing the most swap use.

I get this from /proc/$pid/smaps:

7f2fd1bc4000-7f2fd1d24000 rw-p 00000000 00:00 0 <<< Address range
Size:               1408 kB
Rss:                 900 kB
Pss:                 900 kB
Shared_Clean:          0 kB
Shared_Dirty:          0 kB
Private_Clean:         0 kB
Private_Dirty:       900 kB
Referenced:            4 kB
Anonymous:           900 kB
AnonHugePages:         0 kB
Swap:                508 kB    << Swap used
KernelPageSize:        4 kB
MMUPageSize:           4 kB

3. I use gdb to do core dumps of those address ranges straight to /dev/null

This forces the system to access that memory and pull it out of swap. Going to /dev/null avoids unnecessary IO.

gdb --batch --pid $pid -ex "dump memory /dev/null $astart $aend"

The process I mentioned originally omits any memory regions using less than 1M of swap in order to get the majority of the swap with considerably fewer core dumps, but this is not mandatory.

0

The commands you list are a convenient way to force the kernel to move all necessary pages to RAM and re-enable swap. The reason it is so slow is puzzling - unless you have swap files (rather than partitions) that are hugely fragmented, or you're trying to do this while doing other I/O.

You may want to look at tuning the swappiness value (/proc/sys/vm/). A low value means the system is less likely to page out to disk.

You also might want to enable zswap, which causes pages to be compressed, thus using less swap space. It does use some CPU of course, but this is far less of an impact than having to page in.

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.