为什么Linux不自动清理磁盘缓存和交换?

为什么Linux不自动清理磁盘缓存和交换?

例如,当我归档几GB文件(使用tar)时,Linux使用大量磁盘缓存(和一些交换),但在操作完成后从不清理它。结果,由于没有可用内存,Linux 将尝试从内存中换出某些内容,这反过来又会给 CPU 带来额外的负载。

当然,我可以通过运行来清理缓存echo 1 > /proc/sys/vm/drop_caches,但我必须这样做不是很愚蠢吗?

更糟糕的是,对于交换,没有命令来清理未使用的交换,我必须完全禁用/启用它,我认为这根本不是一件安全的事情。

更新:

我进行了一些测试并发现了一些事情:

  1. 存档命令期间换出的内存页面与存档文件无关,看起来这只是根据交换性由可用内存减少引起的常见换出过程(因为磁盘缓存将其全部吃掉)

  2. 运行swapoff -a实际上是安全的,这意味着交换的页面将移回内存

我当前的解决方案是通过 cgroups 限制存档命令内存使用(我运行带-m标志的 docker 容器)。如果你不用docker,还有一个项目https://github.com/Feh/nocache这可能有帮助。

剩下的问题是Linux 何时会清理磁盘缓存?到底会不会?如果没有,手动清理磁盘缓存 ( echo 1 > /proc/sys/vm/drop_caches) 是一个好习惯吗?

答案1

挑剔:交换所占用的 CPU 时间通常并不重要。当系统在交换过程中响应缓慢时,通常的问题是磁盘时间。

(1) 更糟糕的是,对于swap,没有命令来清理未使用的swap

如果您想触发并等待读回交换的内存,则禁用然后启用交换是一种有效且安全的技术。我只想说“清理未使用的交换”不是正确的描述 - 这不是您想要的永远需要做的。

交换使用量可能看起来比您预期的要高,但这并不意味着它没有被使用。内存页可以同时存储在 RAM 和交换区中。这是有充分理由的。

当交换页被读回时,它不会被专门擦除,并且仍然会被跟踪。这意味着如果该页面需要再次换出,并且该页面自写入交换以来没有发生变化,则不必再次写入该页面。

linux-tutorial.info 也对此进行了解释:内存管理 - 交换缓存

如果内存中的页面被更改或释放,交换空间中该页面的副本将自动释放。

如果您的系统具有相对有限的交换空间和大量 RAM,则可能需要在某个时候从交换空间中删除页面。这是自动发生的。 (内核代码:linux-5.0/mm/swap.c:800

(2) 剩下的问题是 Linux 何时会清理磁盘缓存以及是否会清理?如果没有,手动清理磁盘缓存是否是一个好习惯(echo 1 > /proc/sys/vm/drop_caches)?

Linux 按需清理磁盘缓存。当需要内存时,不活动的磁盘缓存页面将被逐出。

如果更改 的值/proc/sys/vm/swappiness,则可以更改回收非活动文件缓存和回收非活动“匿名”(交换支持)程序内存之间的偏差。默认值已经偏向于交换。如果愿意,您可以尝试swappiness在系统上进一步调低该值。如果您想更多地思考它的swappiness作用,这里有一个示例,可能需要将其转变为向上使或强制 tmpfs 在文件缓存之前进行交换

由于 Linux 会按需清理磁盘缓存,因此一般不建议使用drop_caches.它主要用于测试目的。根据官方文档:

该文件不是控制各种内核缓存(索引节点、目录项、页面缓存等)增长的手段。当系统上的其他地方需要内存时,这些对象会由内核自动回收。

使用此文件可能会导致性能问题。由于它会丢弃缓存的对象,因此可能会花费大量 I/O 和 CPU 来重新创建删除的对象,特别是在它们被大量使用的情况下。因此,不建议在测试或调试环境之外使用。

答案2

这是预期的行为。您可以使用以下命令调整交换使用情况虚拟机交换性sysctl 并根据您的需要进行调整。

相关内容