使Linux读交换回内存


28

当我运行一个使用大部分16GB物理内存的应用程序时,Linux内核会从内存中换出大多数页面。应用程序完成后,每个操作(键入命令,切换工作区,打开新网页等)都需要很长时间才能完成,因为首先需要从交换中读回相关页面。

有没有办法告诉Linux内核将页面从交换复制回物理内存,而无需手动触摸(和等待)每个应用程序?我运行许多应用程序,因此等待总是很痛苦。

我经常使用它swapoff -a && swapon -a来使系统再次响应,但这会清除页面中的交换内容,因此下次运行脚本时需要重新编写它们。

是否有内核接口(也许使用sysfs)来指示内核从swap读取所有页面?

编辑:我确实在寻找一种使所有交换swapcached的方法。(谢谢德罗伯特!)

[ PSserverfault.com/questions/153946/…serverfault.com/questions/100448/…是相关主题,但没有解决如何使Linux内核将页面从交换复制回内存而不清除交换的问题。


您希望所有交换都成为系统内存的缓存吗?因此,您需要可以随意重新加载的系统内存映像吗?基本上,这就是休眠的工作方式-系统将其内存映像到磁盘,关闭电源并在加电时恢复映像。您是否认为,在该线程之后进行查询可能对您有所帮助?例如,如果要对内存进行映像,禁用交换,完成任务,然后恢复映像并重复执行-那是您想做的事情吗?
mikeserv

我认为这不会使swap处于swapcached状态。因此,在我看来,您的建议是swapoff-swapon方法的替代方法。
drrossum 2015年

不,它不会缓存交换(这对我来说有点奇怪),它会在您认为最不可或缺的某个时刻缓存RAM,然后将整个系统内存分配给一些密集型任务,然后再恢复缓存。任务完成了。如果要在密集任务期间进行交换,则只会降低上述任务的速度-您需要额外的时间来交换页面。
mikeserv

Answers:


4

基于最初在此处找到的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

用法:类似

# ./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] [   <=>    ]
# 

它会快速跳过未交换的内存(每秒千兆字节),并在需要交换时放慢速度。


该工具完全可以满足我的需求。谢谢!
drrossum

一件好事是,根据我的观察,交换的页面被复制到RAM中,但是它们并未从交换中删除(至少,大多数不会被删除,因为交换的使用量仅略有减少)。我的解释是,Linux在每个页面上保留两个副本,一个副本在RAM中,一个副本在交换中。如果处理正确,它甚至比再次取消并添加交换更好,因为这意味着当必须再次交换双页时,将不需要其他副本。感谢任何可以确认的内核专家。
Giovanni Mascellani

11

它可能有助于提高/proc/sys/vm/page-cluster(默认值:3)。

从内核文档(sysctl/vm.txt):

页面集群

page-cluster控制页面的数量,一次尝试最多可以从交换中读取连续的页面。这是预读页面高速缓存的交换对象。提到的连续性不是根据虚拟/物理地址,而是在交换空间上连续的-这意味着它们被一起交换了出去。

它是对数值-将其设置为零表示“ 1页”,将其设置为1表示“ 2页”,将其设置为2表示“ 4页”,依此类推。零完全禁用交换预读。

默认值为三(一次八页)。如果您的工作量需要大量交换,则将此值调整为其他值可能会有一些小的好处。

较低的值表示初始故障的等待时间较短,但同时,如果这些故障将成为预读的连续页面的一部分,则额外的故障和后续故障的I / O延迟。

该文档没有提及限制,因此您可以将其设置为荒谬的高值,以使所有交换很快就可以读回。当然,之后再将其恢复为正常值。


这听起来像是一个有用的解决方法。可以将这两种手动干预与sleep命令结合使用,以使其成为单个用户干预。但是,由于它仅从访问的页面连续读取,因此不一定使所有swap swapcache都非常快。到目前为止,这是最好的解决方案。谢谢!
drrossum 2015年

这可能是您将获得的最佳解决方案。我以前从没听说过,但是看起来它将交换变成一系列大IOP,而不是连续的一组小IOP,这可能是导致性能问题的原因。如果能完美地解决您的个人情况,我将感到非常惊讶。
Bratchley

因此,如果由于大量连续的小额换购而导致速度下降,那么即使只是永久性地page-cluster调高价格也可能会提高性能。
Ilmari Karonen 2015年

5

您可以尝试将最关心的程序添加到cgroup并调整swappiness,以便下次应用程序运行添加的程序时,不太可能成为交换对象。

他们的某些页面可能仍会换出,但可能会解决您的性能问题。当程序的许多页面处于交换状态时,其中很大一部分可能只是“停止并启动”行为,程序必须连续暂停以将其页面交换到RAM中,但只能以4k的增量进行。

或者,您可以将正在运行的应用程序添加到cgroup并调整swappiness,以便该应用程序是最倾向于使用交换文件的应用程序。它会降低应用程序的速度,但会保留系统的其余部分。


4

在我看来,您无法神奇地“使系统再次响应”。您要么招致惩罚,要么立即将页面从交换空间读回内存,或者稍后再招致,但是您却招致了一种或另一种方式。事实上,如果你这样做swapoff -a && swapon -a,那么你可能会感到更加的痛苦,而不是减少,因为你会迫使一些页面无法复制回内存,否则将永远不会再次被最终需要丢弃而不读(想:你退出,同时应用程序它的大部分堆都被换出了;可以完全丢弃那些页面,而不必再读回到内存中)。

但这可以清除页面中的交换内容,因此下次我运行脚本时需要重新编写它们。

好吧,几乎所有从交换复制回主内存的页面都将被修改,因此,如果将来需要将其移回以再次交换,则无论如何都必须重新写入它。请记住,交换主要是堆内存,而不是只读页面(通常由文件支持)。

我认为您的swapoff -a && swapon -a技巧与您能想到的一切一样好。


那就是我们两个人在同一时间说完全相同的事情;)
goldilocks 2015年

@goldilocks是的,我看到您的回答在我的准备就绪之前就出现了,但是我已经完成了,所以我坚持了下来:-)
Celada 2015年

您和goldilocks说的是同一句话,但我不认为这是交换缓存的工作方式。我的理解是您可以同时在交换和内存中拥有页面。交换页面仅在内存中的页面更新后才失效。
drrossum 2015年

我相信David Spillett提到的答案是正确的:您确实可以同时在swap和RAM中有一个页面……但是只能在RAM版本被修改之前。然后,您必须丢弃掉交换中的过期副本。当我说“几乎所有从交换复制回的页面都将要被修改”时,我的意思是我希望大多数情况下都会发生这种情况,所以我不希望页面在两个地方都是值得担心的重要部分。
Celada 2015年

您的使用情况可能有所不同:您可能有很多具有大堆的应用程序,这些应用程序经常被读取而不被写入。我的感觉是,大多数人没有这种情况。但是,如果您这样做,我想您是对的:swapoff -a && swapon -a不会对您有好处。我猜在那种情况下,您需要扫描/proc/<each-process>/mem和读取内存的每一页的内容以确保它存在于RAM中。不知道那是否存在。
Celada

0

这里有一个很好的讨论http://rudd-o.com/en/linux-and-free-software/tales-from-responnessnessland-why-linux-feels-slow-and-how-to-fix-that 归结为降低可交换性,其思想是增加系统的感知响应能力,应防止交换代码(这就是发生的情况)。这并不是您问题的真正答案,但这可能会阻止问题出现(您的应用程序不会被交换,只有未使用的数据和页面缓存)


虽然从理论上讲这可以回答问题,但最好在此处包括答案的基本部分,并提供链接以供参考。
slm
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.