New anser 2023!
Some tips and tricks
In addition to all existing answer I want to share some tricks I use.
Reading free's output
First, ensure that output of free is not localized, for this you have to prepend command by LANG=C free -k:
total used free shared buff/cache available
Mem: 32739720 9436264 8704992 883044 15959152 23303456
Swap: 23437308 5450752 17986556
Where, if you compute buff/cache + available the result will be bigger than total! This is wrong!!
Just consider if available mem is bigger than used swap, before purging swap!
msgs=("NOT " "")
{ # read `free` output, ignore 1st line and all values but free and swaped.
read _
read -r _{,,,,,} avail
read -r _ _ swaped _
} < <(LANG=C free -k)
printf 'Avail: %d swaped: %d Can %sunswap!\n' \
"$avail" "$swaped" "${msgs[ avail > swaped ]}"
Avail: 23303456 swaped: 5450752 Can unswap!
Alternative using /proc/meminfo instead of free
Accessing directly /proc/meminfo instead of running a fork to free, you could obtain same values by:
msgs=("NOT " "")
while read field val _; do
case $field in
MemAvailable: ) avail=$val ;;
SwapTotal: ) declare -i swaped=$val ;;
SwapFree: ) swaped+=-$val; break ;;
esac
done < /proc/meminfo
printf 'Avail: %d swaped: %d Can %sunswap!\n' \
"$avail" "$swaped" "${msgs[ avail > swaped ]}"
Avail: 23303456 swaped: 5450752 Can unswap!
Purging swap swapoff -a.
I've build a little script that
- correctly parse
free's output,
- show human readable swaped and avail memory,
- offer to run
swapoff - swaponn loop if user don't interact
- then compute elapsed time used to
unswap.
There is my bash script, based on bash V>5.0:
#!/bin/bash
msgs=("NOT " "")
while read field val _; do
case $field in
MemAvailable: ) avail=$val ;;
SwapTotal: ) declare -i swaped=$val ;;
SwapFree: ) swaped+=-$val; break ;;
esac
done < /proc/meminfo
txtsize() { # Convert integer into readable string, store result in $2 varname
local i=$(($1>=1<<50?5:$1>=1<<40?4:$1>=1<<30?3:$1>=1<<20?2:$1>1023?1:0))
local a=(K M G T P)
((i>4?i+=-2:0)) && a=(${a[@]:2}) && set -- $(($1>>20)) $2
local r=00$((1000$1/(1024*i)))
printf -v $2 %.2f%s ${r::-3}.${r: -3} ${a[i]}
}
txtsize $avail havail
txtsize $swaped hswaped
printf 'Avail: %s (%d) swaped: (%s) %d Can %sunswap!\n'
"$havail" $avail "$hswaped" $swaped "${msgs[ avail > swaped ]}"
if (( avail > swaped )); then
if read -sn 1 -t 5 -p\
'Proceed in 5 seconds. Hit any key to stop now. '; then
echo $'\nUser abort.'
exit 0
fi
echo
elapsedTime=${EPOCHREALTIME/.}
swapoff -a
elapsedTime=00000$(( ${EPOCHREALTIME/.} - elapsedTime ))
swapon -a
elapsedMin=$(( 10#$elapsedTime / 60000000 ))
elapsedSec=00000$(( 10#$elapsedTime % 60000000 ))
printf 'Swap: %s purged in %d minutes and %.3f secs (%.4f").\n' \
"$hswaped" "$elapsedMin" ${elapsedSec::-6}.${elapsedSec: -6} \
${elapsedTime::-6}.${elapsedTime: -6}
fi
His ouptut look like:
Avail: 23.86G (25023596) swaped: (1.14G) 1192460 Can unswap!
Proceed in 5 seconds. Hit any key to stop now.
Swap: 1.14G purged in 1 minutes and 51.166 secs (111.1661").
This script require root privilege. But you could edit them to add sudo before swapoff -a and swapon -a.
From there, as this opereation could take some time, I've built a Full purgeSwap script, showing progression with a nice progress bar and compute end time estimation, you my download here: purgeSwap.sh.
This answer is linked to this other one: How to find out which processes are using swap space in Linux?
About swapiness
I'm not totally convinced on how this compute percent of used memeory: including swap or not... For my tests, I'v seen swaping a lot before reaching percents configured in this kernel variable.
Anyway, for my servers, I still use:
echo 10 > /proc/sys/vm/swappiness
for running system that was not already configured by:
echo >/etc/sysctl.d/90-swapiness.conf 'vm.swappiness = 10'
before last reboot.
Use of vmstat 1 and instant graphs.
If you run:
vmstat 1
You will see regular dump, every 1 seconds of memory status.
I often use this, then, as I like graphical presentation, I've build (in 2009, it's not new, but still usefull)
a perl CGI, that could work in standalone mode and push a little web server:
http://perso.f-hauri.ch/~felix/marcm/vmstat.cgi
This script is self-downloadable, work as a CGI in any web server, but could be used directly on poor systems, they will listen his own TCP port. Graphics are drawn in svg and rendered directly by your browser.
Sample of use:
wget -O vmstat.pl http://perso.f-hauri.ch/~felix/marcm/vmstat.cgi/download/vmstat.cgi
LANG=C perl vmstat.pl
CGI::Pretty is DEPRECATED and will be removed in a future release. Please see https://github.com/leejo/CGI.pm/issues/162 for more information at /usr/share/perl5/CGI/Pretty.pm line 20.
Server started at port 8881
Yes, it's an old script Don't run them as root!!.
...Then you could connect with a browser:
http://ip.add.re.ss:8881/
http://127.0.0.1:8881/?delay=1&width=1800&height=80
Here 1'800 dots with a delay of 1 seconds make half hour graphs.