如果 Linux 缓存太大,为什么 QEMU 不能分配内存?

Mar*_*cus 9 cache kernel qemu linux-kernel

如果我使用我的机器 [Ubuntu 16.04 64 位,内核 4.4] 一段时间,QEMU 需要删除内核缓存,否则,它将无法分配 RAM。

为什么会发生?

这是一个示例运行:

~$ free -m
              total        used        free      shared  buff/cache   available
Mem:          15050        5427        3690          56        5931        4803
Swap:             0           0           0

~$ sudo qemu-system-x86_64 -m 10240 # and other options
qemu-system-x86_64: cannot set up guest memory 'pc.ram': Cannot allocate memory

~$ echo 3 | sudo tee /proc/sys/vm/drop_caches
3

~$ free -m
              total        used        free      shared  buff/cache   available
Mem:          15050        1799        9446          56        3803        9414
Swap:             0           0           0

~$ sudo qemu-system-x86_64 -m 10240 # and other options
qemu-system-x86_64: cannot set up guest memory 'pc.ram': Cannot allocate memory

~$ echo 3 | sudo tee /proc/sys/vm/drop_caches
3

~$ free -m
              total        used        free      shared  buff/cache   available
Mem:          15050        1502       10819          56        2727       10784
Swap:             0           0           0

~$ sudo qemu-system-x86_64 -m 10240 # and other options
# Now QEMU starts
Run Code Online (Sandbox Code Playgroud)

Dav*_*rtz 19

并非所有缓存数据都可以立即丢弃。例如,缓存的脏页必须先写回磁盘,然后才能从 RAM 中删除。您没有交换区,因此在这些写入完成之前,QEMU 根本没有足够的可用空间。

您确实应该添加合理数量的交换。你不能指望内存管理器在一只手被绑在背后的情况下做得很好。

  • @hexafraction 这样想。如果内核在理论上确实具有此功能以阻止 malloc 否则会失败,则没有其他 API 将无法实现当前行为。另一方面,当前的实现允许想要等待并重试一段时间的软件以慢速循环重试 malloc,直到满足为止。 (3认同)
  • @hexafraction 只是一个猜测:这在技术上可能是可行的(但可能会增加显着的复杂性,不确定),但内核开发人员可能会争辩说不需要该功能,因为它解决的唯一问题是没有交换引起的,这还会导致其他问题,如果您只启用交换并让内核按照它已经编码的方式进行内存管理,所有这些问题都会得到解决。 (2认同)
  • @hexafraction 真的,你想等待 30 秒 - 或几分钟 - 为你的 `malloc()` 调用 _maybe_ 找到足够的内存吗? (2认同)