交换事件后立即释放交换空间

交换事件后立即释放交换空间

我使用 Linux 机器进行大量计算工作,有时特定的计算会占用大量 RAM。当我完成后,我最终会得到一堆已使用的交换空间和一堆可用内存,如果我像往常一样继续我的业务,​​机器上的所有其他进程都会有点滞后,直到它们被交换回来如果有一个命令可以将所有内容快速分页回 RAM,这样我就可以运行它,然后起身去洗手间或其他地方,当我回来时,一切都会变得很快,这似乎会很好。 。

我发现这个问题这表明你可以通过以下方式完成此操作(至少在 Linux 上)

sudo swapoff -a
sudo swapon -a

但当我尝试这样做时,需要永远- 它仅以 2-5 MB/秒的速度释放交换空间,即方式低于它应有的能力,而且似乎不值得。这是正常的吗?有没有办法加快这个过程,使其在“去洗手间”的时间而不是“出去吃午饭”的时间运行?

答案1

我最近遇到了同样的问题,并创建了这个来快速清理交换:

#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 

如果这在您的特定环境中不起作用,则过程如下:

1. 获取消耗交换空间最多的进程的列表。

就我而言,我正在检查 /proc/$pid/status,并在 VmSwap 行中使用交换。

# 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. 对于高交换进程,我找到了交换使用最多的内存地址范围。

我从 /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. 我使用 gdb 将这些地址范围直接转储到 /dev/null

这会强制系统访问该内存并将其从交换区中拉出。转到 /dev/null 可以避免不必要的 IO。

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

我最初提到的过程省略了使用少于 1M 交换的任何内存区域,以便通过相当少的核心转储获得大部分交换,但这不是强制性的。

答案2

您列出的命令是强制内核将所有必要的页面移至 RAM 并重新启用交换的便捷方法。它如此缓慢的原因令人费解 - 除非您有大量碎片的交换文件(而不是分区),或者您试图在执行其他 I/O 时执行此操作。

您可能需要考虑调整swappiness值 ( /proc/sys/vm/)。较低的值意味着系统不太可能将页面调出到磁盘。

您可能还需要启用zswap,这会导致页面被压缩,从而使用更少的交换空间。当然,它确实使用了一些 CPU,但这远比页面调入的影响要小。

相关内容