drr*_*sum 33 linux kernel memory swap sysfs
当我运行使用大部分 16GB 物理内存的应用程序时,Linux 内核会从内存中换出大部分页面。应用程序完成后,每个操作(键入命令、切换工作区、打开新网页等)都需要很长时间才能完成,因为首先需要从交换中读回相关页面。
有没有办法告诉 Linux 内核将页面从交换区复制回物理内存,而无需手动接触(和等待)每个应用程序?我运行了很多应用程序,所以等待总是很痛苦。
我经常swapoff -a && swapon -a
用来使系统再次响应,但这会从交换中清除页面,因此下次运行脚本时需要再次写入它们。
是否有内核接口(可能使用 sysfs)来指示内核从交换中读取所有页面?
编辑:我确实在寻找一种方法来使所有交换交换缓存。(感谢德罗伯特!)
[PS serverfault.com/questions/153946/...和serverfault.com/questions/100448/...是相关主题,但没有解决如何让Linux内核在不清除swap的情况下将页面从swap复制回内存的问题。]
der*_*ert 13
它可能有助于提升/proc/sys/vm/page-cluster
(默认值:3)。
来自内核文档 ( sysctl/vm.txt
):
页簇
page-cluster 控制在一次尝试中从交换中读入连续页的页数。这是页面缓存预读的交换对应物。提到的连续性不是在虚拟/物理地址方面,而是在交换空间上是连续的——这意味着它们被一起换出。
它是一个对数值 - 将其设置为零表示“1 页”,将其设置为 1 表示“2 页”,将其设置为 2 表示“4 页”等。零将完全禁用交换预读。
默认值为三(一次八页)。如果您的工作负载是交换密集型的,那么将其调整为不同的值可能会有一些小的好处。
较低的值意味着初始错误的延迟较低,但同时额外的错误和后续错误的 I/O 延迟,如果它们是连续页面预读的一部分,则会带来。
文档没有提到限制,所以可能你可以把这个设置得高得离谱,让所有的交换很快被读回。当然,之后将其恢复为正常值。
在我看来,你不能神奇地“让系统再次响应”。您现在要么招致惩罚,要么将页面从交换空间读回内存,要么稍后招致,但以一种或另一种方式招致它。事实上,如果你做这样的事情,swapoff -a && swapon -a
你可能会感到更多的痛苦而不是更少,因为你强迫一些页面被复制回内存,否则这些页面将永远不会被再次使用并最终被丢弃而不被读取(想想:你退出应用程序时它的大部分堆被换出;这些页面可以被完全丢弃而不会被读回内存)。
但这会从交换中清除页面,因此下次运行脚本时需要再次写入它们。
好吧,几乎任何从交换区复制回主内存的页面无论如何都将被修改,因此如果将来需要将其移回以再次交换,无论如何都必须在交换区重新写入。请记住,交换主要是堆内存,而不是只读页面(通常是文件支持的)。
我认为你的swapoff -a && swapon -a
伎俩和你能想出的任何东西一样好。
您可以尝试将您最关心的程序添加到 cgroup 并调整swappiness,以便应用程序下次运行时您添加的程序不太可能成为交换的候选对象。
他们的某些页面可能仍会被换出,但它可能会解决您的性能问题。当程序的许多页面处于交换状态并且程序必须不断暂停以将其页面交换到 RAM 中时,其中很大一部分可能只是“停止和启动”行为,但仅以 4k 为增量。
或者,您可以将正在运行的应用程序添加到 cgroup 并调整 swappiness,以便应用程序是最倾向于使用交换文件的应用程序。它会减慢应用程序的速度,但会节省系统的其余部分。
基于最初在这里找到的memdump 程序,我创建了一个脚本来有选择地将指定的应用程序读回内存。remember
:
#!/bin/bash
declare -A Q
for i in "$@"; do
E=$(readlink /proc/$i/exe);
if [ -z "$E" ]; then
#echo skipped $i;
continue;
fi
if echo $E | grep -qF memdump; then
#echo skipped $i >&2;
continue;
fi
if [ -n "${Q[${E}]}" ]; then
#echo already $i >&2;
continue;
fi
echo "$i $E" >&2
memdump $i 2> /dev/null
Q[$E]=$i
done | pv -c -i 2 > /dev/null
Run Code Online (Sandbox Code Playgroud)
用法:类似
# ./remember $(< /mnt/cgroup/tasks )
1 /sbin/init
882 /bin/bash
1301 /usr/bin/hexchat
...
2.21GiB 0:00:02 [ 1.1GiB/s] [ <=> ]
...
6838 /sbin/agetty
11.6GiB 0:00:10 [1.16GiB/s] [ <=> ]
...
23.7GiB 0:00:38 [ 637MiB/s] [ <=> ]
#
Run Code Online (Sandbox Code Playgroud)
它会快速跳过未交换的内存(每秒千兆字节)并在需要交换时减慢速度。