我有一台8 GB RAM 和 16 GB 交换的 Debian (Buster) 笔记本电脑。我正在运行一个很长的运行任务。这意味着我的笔记本电脑在过去六天里一直处于开机状态。
这样做时,我需要定期将笔记本电脑用作笔记本电脑。这应该不是问题;长时间运行的任务受 I/O 限制,通过 USB 硬盘上的东西工作,并且不需要太多 RAM (<200 MB) 或 CPU (<4%)。
问题是当我几个小时后回到我的笔记本电脑时,它会非常缓慢,可能需要 30 分钟才能恢复正常。这太糟糕了,以至于崩溃监视器将它们各自的应用程序标记为已冻结(尤其是浏览器窗口)并且事情开始错误地崩溃。
查看系统监视器,大约一半使用的 2.5 GB 被转移到交换中。我已通过删除交换空间 ( swapoff /dev/sda8
) 确认这是问题所在。如果我离开它而没有交换空间,即使在 24 小时后它也几乎立即恢复了生机。使用交换,前五分钟几乎是一块砖,只剩下六个小时。我已经确认即使我不在,内存使用量也不会超过3 GB 。
我尝试将交换性(另见:Wikipedia)减少到and的值,10
但0
问题仍然存在。似乎在一天不活动之后,内核认为不再需要整个 GUI 并将其从 RAM 中擦除(将其交换到磁盘)。长期运行的任务是读取庞大的文件树并读取每个文件。所以可能是内核被混淆了,认为缓存会有所帮助。但是在一次扫描具有约 10 亿个文件名的 2 TB USB HD 时,额外的 GB RAM 对性能没有太大帮助。这是一款便宜的笔记本电脑,但硬盘驱动器很慢。它根本无法足够快地将数据加载回 RAM。
如何告诉 Linux 只在紧急情况下使用交换空间?我不想在没有交换的情况下运行。如果发生意外情况,并且操作系统突然需要额外的几 GB,那么我不希望任务被杀死,而是更愿意开始使用交换。但目前,如果我启用交换,我的笔记本电脑将无法在需要时使用。
“紧急情况”的准确定义可能有待商榷。但是要澄清我的意思:紧急情况是系统除了交换或终止进程之外别无选择。
什么是紧急情况?-你真的要问吗?......我希望你永远不会发现自己在燃烧的建筑物中!
我不可能在这个问题中定义所有可能构成紧急情况的东西。但是例如,紧急情况可能是当内核被推送内存以致它开始使用OOM Killer杀死进程时。紧急情况不是内核认为它可以通过使用交换来提高性能。
最终编辑: 我已经接受了一个答案,它完全符合我在操作系统级别的要求。未来的读者还应该注意提供应用级解决方案的答案。
一种解决方法是确保内存 cgroup 控制器已启用(我认为即使在半新的内核中也是默认的,否则您需要添加
cgroup_enable=memory
到内核命令行)。然后,您可以在具有内存限制的 cgroup 中运行 I/O 密集型任务,这也限制了它可以消耗的缓存量。如果您使用的是 systemd,您可以在单元或包含它的切片中设置
+MemoryAccounting=yes
和MemoryHigh
/MemoryMax
或MemoryLimit
(取决于您使用的是 cgroup v1 还是 v2)。如果它是一个切片,您可以使用它在切片systemd-run
中运行程序。来自我的一个系统的完整示例,用于运行具有内存限制的 Firefox。请注意,这使用 cgroups v2 并设置为我的用户,而不是 root(v2 相对于 v1 的优点之一是将其委托给非 root 是安全的,因此 systemd 会这样做)。
我发现要让用户工作,我必须使用切片。系统一只需将选项放在服务文件中(或
systemctl set-property
在服务上使用)即可工作。这是一个示例服务(使用 cgroup v1),请注意最后两行。这是系统 (pid=1) 实例的一部分。
文档位于
systemd.resource-control(5)
.如今进行如此巨大的交换通常是一个坏主意。当操作系统只交换了几 GB 的内存进行交换时,你的系统已经爬到了死地(就像你看到的那样)
最好与小型备份交换分区一起使用
zram
。许多操作系统,如ChromeOS、Android 和各种 Linux 发行版(Lubuntu、Fedora)多年来默认启用 zram,尤其是对于 RAM 较少的系统。它比在 HDD 上交换要快得多,并且在这种情况下您可以清楚地感受到系统的响应能力。在 SSD 上则更少,但根据这里的基准测试结果,即使使用默认的 lzo 算法,它似乎仍然更快。您可以更改为lz4以获得更好的性能,但压缩率会更低。根据官方基准,它的解码速度比 lzo 快近 5 倍事实上, Windows 10和macOS默认也使用类似的页面文件压缩技术
还有,
zswap
虽然我没用过。可能值得一试,比较哪个更适合您的用例之后,另一个建议是降低那些 IO 绑定进程的优先级,并可能让终端以更高的优先级运行,这样即使系统处于高负载状态,您也可以立即在其上运行命令
进一步阅读
内核相信它正在做正确的事情™ 。为什么它将未使用的1内存保留在 RAM 中,因此基本上浪费了它,而不是将其用作缓存或其他东西?
我不认为 Linux 内核是无偿或预期换出页面的,所以如果它这样做,必须在 RAM 上存储其他东西,从而提高你的长期运行任务的性能,或者至少达到这个目标。
如果您提前知道何时需要重新使用您的笔记本电脑,您可以使用
at
命令(或crontab
)来安排交换清理(swapoff -a;swapon -a
)。由于清理交换可能是矫枉过正,甚至触发 OOM 杀手,如果出于某种原因,不是所有的东西都适合 RAM,你可能只是“取消交换” 2与你想要恢复的正在运行的应用程序相关的所有东西。
一种方法是将调试器附加
gdb
到每个受影响的进程并触发核心转储生成:正如您所写,您的长期运行的应用程序不会重用它在初始传递后读取的数据,因此您处于长期缓存无用的特定情况。然后像 Will Crawford 建议的那样使用直接 I/O 绕过缓存应该是一个很好的解决方法。
1
或者,您可能只是在操作系统认为交换您的 GUI 应用程序和环境是一个好主意之前,通过回显或3
到/proc/sys/vm/drop_caches
伪文件定期刷新文件缓存。请参阅如何清空 Linux 系统上的缓冲区和缓存?详情。
1从某种意义上说未使用:在很长一段时间内不再积极使用,内存仍然与其所有者相关。
2放回存储在交换区的 RAM 页。
您正在运行的流程是您自己创建的吗?
如果是这样,可能值得调整您的代码以使用该
O_DIRECT
标志打开文件,该标志引用手册页-这是一个我自己没有尝试过的想法(很抱歉我现在没有时间尝试这个)。
假设您为后台进程创建了一个只有 512MB 内存的小型 VM,我不确定您是否希望它在主机系统上进行任何交换、调用和关闭交换。
删除交换或将其减少约 20%(可能因系统而异),因为最近操作系统不再像过去几年那样使用交换。可能它会回答你的问题:
--> 官方redhat.com
下面的一些红帽信息,
和
https://wiki.debian.org/Swap
上面 Debian 链接的一部分,
你可以试试:
“在 Linux 中禁用交换的最佳方法”
***个人备注:***
因为我有 6 GB RAM 并且在我最近的所有 Linux 操作系统中。我从未见过任何使用 Swap 的迹象。我决定我必须关闭它,要么是为了空间(几 GB 以上),要么是因为它有时会减慢我的系统速度。