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

ode*_*den 2 linux memory swap disk caching

例如,当我归档一些文件(使用 tar)时,Linux 使用了相当多的磁盘缓存(和一些交换),但在操作完成后从不清理它。结果,因为没有可用内存,Linux 会尝试从内存中换出一些东西,这反过来又会给 CPU 带来额外的负载。

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

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

更新:

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

  1. 在归档命令期间换出的内存页面与归档文件无关,这似乎只是一个普通的换出过程,这是由于可用内存减少(因为磁盘缓存把它全部吃光了)根据swappiness

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

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

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

sou*_*edi 6

挑剔:交换使用的 CPU 时间通常并不重要。当交换期间系统响应缓慢时,通常的问题是磁盘时间。

(1) 更糟糕的是交换,没有命令来清理未使用的交换

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

交换使用率可能看起来比您预期的要高,但这并不意味着它没有被使用。一页内存可以同时存储在 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. 它主要用于测试目的。根据官方文档

该文件不是控制各种内核缓存(inode、dentries、pagecache 等)增长的手段,当系统其他地方需要内存时,内核会自动回收这些对象。

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