如果有空闲的内存,如何清空交换空间?

当我打开一个占用大量内存的应用程序(VirtualBox设定为2GB内存),通常会使用一些交换空间,具体取决于我同时打开了什么其他应用。
然而,当我退出最后一个应用程序时,2GB的内存被释放,但交换空间使用量仍然保持不变。
例如,现在距离关闭VirtualBox已经过去两个小时,我有1.6GB的可用内存,交换空间仍然有770MB。
我该如何告诉Ubuntu停止使用交换空间并恢复使用内存?

1最简单的方法是重新启动您的设备,这样可以节省将数据复制到内存中的时间,并且释放内存可以节省笔记本电脑的电力和CPU温度。 - Mohamed Slama
9很大的假设是,重新填充计算机上的所有东西所需的时间比那更少。 - Jono
3Ubuntu 16.04至少可以在不再需要的情况下继续使用交换空间,从而依赖于交换文件使您的系统变得非常缓慢。因此,手动干预可能是有用的。重新启动并不总是一个选择。 - matanster
7个回答

Ubuntu底层的Linux内核会根据需要自动将这些页面从磁盘换入到RAM中,所以一般来说,就让它自然发生吧。
不过,如果你真的觉得有必要强制执行(我可以想象出一种情况,你想知道系统稍后会有响应),你可以暂时禁用并重新启用交换空间。
sudo swapoff -a
sudo swapon -a

或者作为单行

sudo swapoff -a; sudo swapon -a

小心操作,因为这可能会使您的系统不稳定,特别是如果RAM已经很低。确保系统有足够的空闲RAM,否则您可能无法释放交换空间,而OOM-Killer将会终止一些进程。
请注意,关闭交换分区可能需要一段时间。如果您有大量需要关闭的交换空间,这一点尤其重要。

11搞定了,交换已复制到内存中。我猜在运行swapoff之前,你只需要确保至少有与使用的交换空间相同的可用内存,对吗? - jfoucher
13这个交换并没有被复制到RAM中,而只是被禁用了。在执行此操作之前,您应该确保系统不会进行交换。如果您这样做,内核将会看到内存消失,并且OOM-Killer可能会开始随机终止应用程序。您没有必要像这样“清理”交换空间。(请参阅我的其他评论):) - popey
69实际上,交换区基本上是被复制到RAM中的,或者更准确地说,页面在禁用交换区之前会从磁盘交换回RAM中。 - SpamapS
16只有在某个进程仍然需要时,页面才会被复制到RAM中。有时,被交换的页面属于已经完成的进程,内核并不急于立即从交换区中移除这些页面。 - Bruno Medeiros
11这应该是正确的答案,因为这是将交换页面返回到RAM然后清空交换内存的方法。 - Alfonso Jiménez
7这是唯一一个实际回答问题并应该被接受的答案! - pagliuca
1你可以使用watch free -h来查看进度(以大致了解需要多长时间),随着移动的进行,总交换空间和已使用的交换空间将会减少。 - Shelvacu
这确实完成了工作。但在我的情况下不值得:我将4GB换入内存,花了3分钟:前2.5分钟什么都没发生,只有最后30秒才进行了交换。 - HongboZhu
1我实际上制作了一个shell脚本,可以完成这个任务,并将其放置在/usr/bin/reswap中。现在我只需使用一个命令就能完成这个操作。 - unfa
2我正在考虑创建一个Nagios警报,当系统开始交换时会提醒我们。例如,此刻我有一个系统,交换空间使用了8/16G,但只有36/128G的内存在使用。如果Nagios发出警报,我想清除交换空间以使其安静下来。我知道此刻交换空间没有被使用,但Nagios不知道。所以这是一个使用案例,能够"清空"交换空间将非常方便...仅仅作为一种簿记练习。 - Mike S
@jfoucher 我认为你应该将这个答案标记为正确答案,因为它实际上回答了你提出的具体问题。目前的正确答案更多地涉及解释交换出和交换入的工作原理,而不是如何清理交换并将其移动到内存中。此外,你还可以查看Scott Severance的答案,其中包含一个执行相同操作的脚本。 - kapad
swapoff: -a, --all 从/proc/swaps禁用所有交换空间 .................. .................. .................. swapon: -a, --all 从/etc/fstab启用所有交换空间(如果您使用手动交换文件,您必须自己再次添加它,swapon -a不会自动添加 :) ) - jave.web
2根据我的经验,swapoff可能需要很长时间才能完全将交换文件中的内容转移到内存中。不确定原因是什么。 - matanster
我实际上并没有经历过这种情况发生 - matanster
2依我个人看法,应该使用&&,而是用分号(swapoff -a; swapon -a)代替!为什么呢?假设你有多个交换设备。swapoff 可能会在一个设备上成功,但在另一个设备上失败。在这种情况下,swapoff 命令将返回一个非零退出码,导致 swapon -a 命令不会被执行,因此最终得到的交换空间比之前更少 - myrdd
有没有办法只针对单个进程来做这个?可以将它们停止,将所有内容转移到内存中,然后继续进行... - Radio Controlled
我本以为交换会很快转移到RAM中,但实际上并没有"转移"。它只是禁用了交换,并且只要应用程序释放内存,交换就会被清空。所以可能需要几分钟的时间。但我可以通过按下Ctrl+C来停止它:交换只是重新启用,并恢复其余的数据。 - Alcalyn
@Shelvacu 顺便说一下,另一种观察进度的方式是使用图形用户界面(例如,如果你在使用Ubuntu),它内置了系统监视器,可以显示交换空间的使用情况。 - whyer
1@matt 我确认速度非常慢,但你并没有说具体有多慢(这对某些人来说可能很有意义)。在我的情况下,大约每秒1兆字节。例如,如果我有8GB的内存和8GB的交换空间,并且我的交换空间使用了15%,那么释放它大约需要20分钟!时间太长了。在这段时间里,我的一个CPU核心一直处于100%繁忙状态。我有4个核心,所以CPU的利用率为25%。也许这些信息对于那些正在考虑是否应该尝试的人会有帮助。 - whyer
生活变得更美好了,有了这个升级命令!再也不需要重新启动我的Debian。每个Linux用户都应该知道这些命令。 - Brian Cannard
根据将所有内容移出交换空间所需的时间长短,最好运行sudo bash -c "swapoff -a; swapon -a",以避免可能需要两次输入密码的情况。 - b_laoshi
在一个运行中的系统上进行这个操作,比如与数据库一起使用,是否安全?在swapoff/swapon运行期间,会明显减慢整个系统的速度吗? - robsch
sudo swapoff -a会永久禁用交换空间吗?我不在意交换空间,因为我有64GB的内存,它只会使事情变慢。 - m4l490n

只因为交换空间被分配了,并不意味着它正在被“使用”。虽然像系统监视器和top这样的程序会显示一些交换空间被分配(例如770MB),但这并不意味着系统正在主动进行交换。
要查看是否有任何交换操作,您可以使用vmstat命令。让它运行几秒钟以稳定下来,观察si(swapin)和so(swapout)列。如果没有发生任何交换操作,那就没有理由担心。
以下是运行vmstat 1的输出,您可以看到我的机器根本没有进行交换。
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa
 0  0  78588 230788   9596  72196    0    0     0     0  543  652 12  6 78  0
 0  0  78588 230780   9596  72196    0    0     0     0  531  410  1  0 99  0
 0  0  78588 230796   9596  72196    0    0     0     0  300  335  1  1 97  0
 1  0  78588 230788   9608  72224    0    0    40     0  737  762  4  4 84  8
 5  0  78588 230788   9608  72224    0    0     0     0  415  385  9  3 84  0
 0  0  78588 230540   9616  72224    0    0     0    44  611  556 55  5 31  0
 0  0  78588 230532   9616  72224    0    0     0     0  574  662  1  6 89  0

在这里,你可以看到我已经分配了交换空间:top
Mem:    475236k total,   245076k used,   230160k free,     9720k buffers
Swap:   491512k total,    78588k used,   412924k free,    72476k cached

54没有理由担心,直到我继续使用被替换掉的某个应用程序,然后一切都乱了套。 - törzsmókus
291这篇帖子没有回答问题。 - emchristiansen
23这个问题的前提是基于误解的。这篇帖子解决了这些误解。 - popey
52我并没有看到误解,我只是看到对于“使用”一词的理解存在分歧。你所指的“使用”是指主动进行进出交换,而原始问题似乎是以“使用”表示已经发生了数据交换,可能稍后需要再次交换回来。在大量其他内存被交换出去的事件之后,希望清除交换区是有合理理由的,这实际上是预先阻止用户知道将会发生的主动交换(尤其是如果稍后的“反交换”可能会在磁盘因其他原因而负载较重时发生)。 - drfrogsplat
56运行了一个内存密集型应用程序后,当我切换到其他应用程序时,它们都没有响应,可能是因为被交换出去了。希望系统能有一种告诉它尽量将数据交换回来的方法(然后休个咖啡时间),这比每次按Alt+Tab都要等待20秒要好。 - Mark K Cowan
我尝试了 vmstatsi & so 命令,发现系统处于空闲状态。然后我尝试了 swapoff 命令。这一次,我可以看到交换空间正在减少,主内存正在分配。 - user37089
5问题的标题特别询问如何清空交换空间。例如,如果可用的交换空间少于500 MB,Oracle安装程序将无法运行某些(任何)命令,即使有200+GB的空闲内存也无济于事。无论交换空间是否正在被活动使用,总会有一些东西占用它。在大多数情况下,不活跃的交换空间使用可能会导致任务切换变慢,而在其他情况下可能会破坏功能。 - jbo5112
3这并没有回答问题! - pagliuca
1这对于交换区内有无用数据的情况也是无效的。我曾经在一个2GB的交换区上使用了swapoff swapon的技巧,但在它在内存中活动时,只占用了500MB的空间。 - John Hamilton
我已经做过这个,但现在htop显示交换空间使用量为0k/0k,就好像交换空间不再可用一样... - Fez Vrasta
2如果什么都没有发生,那就没有理由担心。我觉得这很难相信。我曾经进行了一些内存密集型的计算,导致使用了交换空间,但在终止计算后,又有了多余的RAM,交换空间仍然保持满载状态,而且Firefox的响应速度变慢了。终止Firefox后,交换空间释放了很多,重新启动后,Firefox的速度又恢复了。我预计操作系统在处理交换空间方面并不总是高效的。 - Herbert
@emchristiansen 它不仅仅是回答问题,还提供了一些关于内核和分页的内部工作原理的见解。 - Louis Waweru
这并没有回答问题。我正在使用的应用程序在启动时需要一定数量的交换空间,否则它会崩溃。Linux 是否在进行交换并不重要。 - Étienne

你还可以将"swappiness"值从默认的60设置为其他值,这样交换空间就不会一开始就变得过大。为什么出货时默认设置为60而推荐值是10,这让我感到困惑。来自Ubuntu SwapFAQ
在Ubuntu中,默认设置是swappiness=60。减少swappiness的默认值可能会提高典型Ubuntu桌面安装的整体性能。推荐的swappiness值是10,但也可以随意尝试其他值。
通过将该值更改为10甚至0,您可以显著提升旧系统和慢速驱动器的速度。将该值设置为0并不会关闭Linux内核3.4及以下版本的交换空间,但在3.5+版本中会关闭,因此如果您希望保持最低设置,则应使用值为1。
我看不出为什么不将此设置为0,因为任何写入磁盘的操作都比RAM慢。我有8个虚拟核心,一个快速的SSD和8GB内存,我的交换空间设置为0。此刻我有3个虚拟机正在运行,我的内存使用量是7.1GB中的7.7GB,我的已使用交换空间只有576KB中的952MB,所有系统都运行顺畅!
根据Ubuntu SwapFAQ中的链接
swappiness参数控制内核将进程从物理内存移到交换磁盘的倾向。由于磁盘比RAM慢得多,如果过于积极地将进程移出内存,这可能导致系统和应用程序的响应时间变慢。
swappiness可以取0到100之间的值。 swappiness=0告诉内核尽可能避免将进程从物理内存中交换出去。 swappiness=100告诉内核积极地将进程从物理内存中交换出去并将它们移动到交换缓存中。
以下是检查swappiness、清空交换分区并将swappiness更改为0的基本说明:
要检查swappiness值:
cat /proc/sys/vm/swappiness

临时将交换空间设置为0(如SpamapS建议):

这将清空你的交换空间,并将所有的交换空间转移到内存中。首先确保你有足够的可用内存,方法是查看gnome-system-monitor的资源标签页,你的可用内存应该大于已使用的交换空间。此过程可能需要一段时间,请使用gnome-system-monitor来监视和验证进展。

sudo swapoff --all

将新值设置为0:
sudo sysctl vm.swappiness=0 

重新打开交换功能:
sudo swapon --all

要永久将swappiness设置为0:

  1. sudoedit /etc/sysctl.conf
  2. 添加以下行 vm.swappiness = 0
  3. sudo shutdown -r now # 重新启动系统

* 在内核版本3.5+中,将swappiness设置为0会完全关闭它,如果您想要最低的swappiness算法,则建议将其设置为1。来源:https://www.percona.com/blog/2014/04/28/oom-relation-vm-swappiness0-new-kernel/


2我刚刚更新了答案,提供一个永久设置 swappiness 的方法。不确定它为什么得到这么多赞,我猜想没有人测试过。 - Elijah Lynn
1在这个答案中,有更多关于swappiness的好阅读 => http://askubuntu.com/a/103916/11929 - Elijah Lynn
增加了关于swappiness=0行为在Linux内核版本3.5+中的变化的说明。 - Elijah Lynn
嗨。感谢你的好回答。我建议,就像你在最后几行中提到的(带有*),相应地修改整个回答(也就是将swappiness设置为1而不是0)。我相信这样会使回答更加一致。 - miro marchi
3我不确定作者最初发布答案时是否可用,但是在Ubuntu服务器安装中,swappiness值为"60",因为该环境具有不同的性能规格。https://help.ubuntu.com/community/SwapFaq#What_is_swappiness_and_how_do_I_change_it.3F - Frito
为什么你一开始要使用交换空间,然后又将其设置为0?如果你真的想禁用交换空间,我更愿意回收那些磁盘空间。^^ - xeruf
由于在3.4及更低版本的内核中无法关闭swapiness,唯一的方法是将swapiness设置为0,在3.5及更高版本中,将swapiness设置为0即可禁用它。 - Elijah Lynn
2这个设置非常有效地控制了交换空间的大小。我的系统有16G的内存和16G的交换空间。有时候我同时运行两个虚拟机,其中一些应用程序被交换出去。当我关闭虚拟机后,内存使用量下降了,但是交换空间的使用量仍然保持不变,导致我在切换应用程序时系统卡顿。调整交换空间的使用策略对我来说改善了性能。 - kapad
1这应该是被接受的答案。问题得到了详尽的解释,以及解决方案,还附带链接和保留Swap内存的方法,但也有助于在第一时间将其控制在合理范围内。真是很棒的东西。谢谢。 :) - Jack_Hu
3.5+还有效吗?我使用的是4.15内核,swappiness设置为0,交换空间仍然起作用(但只在真正需要时)。 - jave.web
实际上,我发现在使用swappiness值为70甚至80(Arch Linux,内核5.3)时,响应速度和交换时间都最佳。是的,使用较低的swappiness值可以减少内核的内存交换频率,但当它确实发生时...祝你好运,等待长达5分钟才能重新控制鼠标光标。 - Marc.2377

我发现清空交换空间对于磁盘速度较慢且内存有限的系统非常有帮助。当然,正如之前提到的那样,要做到这一点的方法是运行sudo swapoff -a; sudo swapon -a。问题在于,如果内存不足,这样做会导致各种问题。
我写了一个脚本,我称之为toggle_swap,在过去几年中一直对我有效。它会在实际禁用交换空间之前检查是否有足够的可用内存。以下是脚本内容:
#!/bin/bash

free_data="$(free)"
mem_data="$(echo "$free_data" | grep 'Mem:')"
free_mem="$(echo "$mem_data" | awk '{print $4}')"
buffers="$(echo "$mem_data" | awk '{print $6}')"
cache="$(echo "$mem_data" | awk '{print $7}')"
total_free=$((free_mem + buffers + cache))
used_swap="$(echo "$free_data" | grep 'Swap:' | awk '{print $3}')"

echo -e "Free memory:\t$total_free kB ($((total_free / 1024)) MB)\nUsed swap:\t$used_swap kB ($((used_swap / 1024)) MB)"
if [[ $used_swap -eq 0 ]]; then
    echo "Congratulations! No swap is in use."
elif [[ $used_swap -lt $total_free ]]; then
    echo "Freeing swap..."
    sudo swapoff -a
    sudo swapon -a
else
    echo "Not enough free memory. Exiting."
    exit 1
fi

太棒了,我一直在寻找这样的东西。也许为了更安全起见,你可以先呈现数字和百分比,然后再询问,以确保绝对正确。 - Atherion
4我已更新代码并创建了一个基于 https://gist.github.com/Jekis/6c8fe9dfb999fa76479058e2d769ee5c 的 gist。 - Jekis
这是我在阅读了所有提示后得出的结论,比如应该在结束交换之前确保确实有足够的RAM。感谢您先生,这是一段很棒的脚本。它应该默认包含在Ubuntu中(不是开玩笑,它真的是必备品)。 - Apache
除非你在关闭交换空间之前运行任何新的东西,并且在重新打开之前 - 它将没有足够的内存。 - barteks2x
这取决于你有多少可用内存。如果有足够的可用内存来容纳所有交换空间和新进程,那就没有问题。如果不够的话,你是对的。 - Scott Severance
这真的比将/proc/sys/vm/swappiness从默认值70降低到10或20更有效吗?内核仍会在需要时进行交换,但是它的交换行为会相对温和一些。你是否真的发现系统变慢了,还是只是喜欢看到较低的交换使用率数字? - Peter Cordes
哦,你是手动使用这个而不是第一次使用时一切都变慢。最近有一个问题询问如何在每小时的cron作业中使用swapoff/swapon,并且有一个答案链接到这里。我个人认为,即使你检查确保有足够的内存,那也听起来像个坏主意。对于手动取消所有交换的脚本,这是对这个问题的一个很好的答案。 - Peter Cordes
释放交换空间... swapoff: /dev/sdb5: 交换空间关闭失败:无法分配内存 swapoff: /dev/sda5: 交换空间关闭失败:无法分配内存 - Constantin De La Roche
尝试手动运行swapoffswapon命令,看看是否会出现错误。如果是这样,那就是一个独立的问题。 - Scott Severance
2023年 - 适用于 PopOS 22.04 的工作箱 - MarcoZen

在折腾了几天的swappiness之后,我得出的结论是内核应该自己处理。它知道自己在做什么,并且已经优化过,以提供最佳体验。
除非你有一个非常好的理由想要那个磁盘回来,否则我建议不要去碰它。

8我在交换空间中有一些东西,vmstat向我显示正在进行swapin和swapout操作,而Chrome却非常卡顿,而我的CPU几乎没有被使用。这个原因足够好了,不是吗? - xeruf
1在桌面上进行某些交换操作确实会导致卡顿的情况发生。(不仅仅是在交换过程中,而且在之后,即使有足够的内存,在很长一段时间内也会出现。)因此,最好的答案只是主观经验,在某些情况下会发生。 - Cray

告诉虚拟机不要那么频繁地进行交换,通过降低交换性能来实现。
sudo sysctl vm.swappiness=10

或者尽量不要过于频繁地进行交换。
sudo sysctl vm.swappiness=0

请阅读此处的swapfile文档: https://help.ubuntu.com/community/SwapFaq

如果你的交换空间被占用,它不会影响性能。唯一的性能损失是在交换空间中进行数据的读写操作。如果没有任何数据被交换进入或交换出去,那么你就不需要担心任何问题。

13是的,但如果某些东西正在被交换,它确实会影响性能,因此才有这个问题。 - quant
1这真是一些胡言乱语,通常大规模的回退交换都发生在硬盘驱动器上,或者一般来说是在比内存更慢的设备上——如果空间不足,已有的内容就会被交换出去,比如互联网浏览器,然后你实际上就是从较慢的设备上使用它了... - jave.web
通常在 RAM 空间耗尽之前,内存就会被交换出去。这由 vm.swappiness 参数控制。一旦 swap 空间被占用,当访问已被交换到磁盘的内存页时会产生性能影响。 - lanoxx