尽管有可用内存,但仍在进行进程交换

尽管有可用内存,但仍在进行进程交换

由于某种原因,我们的系统在使用内存约为 60GB 时开始交换(主动使用的内存)。(参见下面的编辑,似乎 I/O 和磁盘缓存的使用情况,甚至以前运行的进程都有影响)关闭它(swapoff-a)进行测试导致 bad_alloc 一次(我猜是因为当时有更多进程也在使用内存)但也使我的程序速度提高了 10 倍以上。

这重现了该问题(没有其他重要进程运行,编辑:参见下文,仅当 I/O 密集型进程之前不久运行才会发生这种情况):

#include <cstdio>
#include <vector>

int main() {
  size_t bytes = size_t(80) * 1024 * 1024 * 1024; // 80GB
  size_t* data = new size_t[bytes / sizeof(size_t)];
  for (size_t i = 0; i < bytes / sizeof(size_t); ++i) {
    data[i] = i;
  }
  for (;;) {}
}

在使用内存约 60GB 时,系统开始交换,CPU 使用率降至 100% 以下(我猜是因为该过程现在受 I/O 限制)。

系统是Ubuntu 14.04,64位:

Linux ... 3.13.0-77-generic #121-Ubuntu SMP Wed Jan 20 10:50:42 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

一旦达到这一点,free -m 将给我以下结果:

              total        used        free      shared  buff/cache   available
Mem:          96671       55504         358          60       40808       40478
Swap:         47679       19366       28313

当 swappiness=1 时问题仍然存在(如果刚刚运行了 I/O 密集型程序,尤其是对于我的实际罪魁祸首(不是上面的代码)来说,它同时执行了大量的 I/O 并使用了大量的内存。如果最近几乎没有 I/O,则上述程序将分配所有内存并且不会交换!

如果长时间内没有 I/O 密集型操作,问题就会消失。似乎操作系统以某种方式使我的应用程序进行交换,因为它认为磁盘缓存更有价值 - 即使在交换量非常低的情况下也是如此。我不明白这种行为,因为磁盘缓存内存应该与可用内存一样好,而且肯定不会在正在运行的进程上触发交换。

最初,我的问题发生在一个读取大文件并占用大量内存的应用程序中。之后,它一直持续到上面根本没有 I/O 的示例代码。最后,当我稍后启动示例代码时,没有发生交换。

答案1

64 GB 似乎是支持 PAE 的 32 位 Ubuntu 的极限: https://help.ubuntu.com/community/32bit_and_64bit

32 位计算机的字长为 32 位,理论上内存限制为 4GB。通过使用“物理地址扩展”(PAE),这一限制得到了扩展,将限制提高到 64GB,尽管 4GB 以上的内存访问速度会略慢。

答案2

检查vmstat一下siso(交换入/出)是否真的填充了任何交换。即使将 swappiness 设置为 0,交换也可以分配交换。

相关内容