Почему QEMU не может выделить память, если кэши Linux слишком велики?

9

Если я какое-то время пользуюсь моей машиной [Ubuntu 16.04 64 bit, kernel 4.4], QEMU необходимо удалить кэши ядра, в противном случае ему не удастся выделить оперативную память.

Почему это происходит?

Это примерный прогон:

~$ 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
Маркус
источник
4
Потому что у вас нет никакого обмена.
Майкл Хэмптон

Ответы:

19

Не все кэшированные данные могут быть немедленно удалены. Например, кешированные грязные страницы должны быть записаны обратно на диск, прежде чем их можно будет удалить из ОЗУ. У вас нет свопа, поэтому до тех пор, пока эти записи не завершатся, для QEMU просто не хватит места.

Вы действительно должны добавить разумное количество свопа. Вы не можете ожидать, что менеджер памяти сделает хорошую работу с одной рукой, связанной за его спиной.

Дэвид Шварц
источник
1
В качестве теоретического вопроса (поскольку я хотел бы узнать больше о том, как на самом деле работает управление памятью), почему менеджер не может задерживать (блокировать) попытки выделения памяти QEMU во время записи грязных страниц?
нанофарад
2
@hexafraction Просто предположение: это, вероятно, технически возможно (но может добавить значительную сложность, но не уверен), но разработчики ядра, вероятно, утверждают, что эта функция не нужна, потому что единственная проблема, которую она решает, вызвана отсутствием свопа, что также вызывает другие проблемы, которые устраняются, если вы просто включаете swap и позволяете ядру управлять памятью так, как оно уже написано, для успешной работы.
mtraceur
1
@hexafraction Ядро понятия не имеет, что разумно сделать. Для некоторых приложений это не имеет смысла, поэтому это не общая политика. QEMU решил не делать этого.
Дэвид Шварц
2
@hexafraction Действительно, вы хотите ждать 30 секунд - или несколько минут - для malloc()вызова возможно найти достаточно памяти?
Майкл Хэмптон
3
@hexafraction Подумай об этом так. Если бы ядро ​​теоретически имело эту функцию, чтобы блокировать какое-то время, если malloc в противном случае потерпел бы неудачу, не было бы никакого способа достичь текущего поведения без дополнительных API. С другой стороны, текущая реализация позволяет программному обеспечению, которое хочет подождать и повторить некоторое время, повторить попытку malloc в медленном цикле, пока это не будет удовлетворено.
Vality