Чому QEMU не може виділити пам'ять, якщо кеші Linux занадто великі?


9

Якщо я деякий час використовую свою машину [Ubuntu 16.04 64 біт, ядро ​​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 Лише здогадка: це, мабуть, технічно можливо (але це може додати значних складностей, не впевнений), але розробники ядра, напевно, стверджують, що в цій функції немає необхідності, тому що єдину проблему, яку він вирішує, викликано відсутністю заміни, яка також спричиняє інші проблеми, які все виправлено, якщо ви просто включите своп і дозволите ядру виконувати управління пам’яттю так, як це вже закодовано.
mtraceur

1
@hexafraction Ядро не має уявлення, що це розумно робити. Для деяких додатків це не має сенсу, тому це не загальна політика. QEMU вирішила цього не робити.
Девід Шварц

2
@hexafraction Дійсно, ви хочете почекати 30 секунд - або кілька хвилин -, щоб ваш malloc()дзвінок, можливо, знайшов достатню кількість пам’яті?
Майкл Хемптон

3
@hexafraction Подумайте про це так. Якщо у ядра теоретично була ця функція блокувати деякий час, якщо інакше не вдасться вийти з ладу, не було б способу досягти поточної поведінки без додаткових API. З іншого боку, поточна реалізація дозволяє програмному забезпеченню, яке хоче почекати і повторити деякий час, щоб повторити спробу malloc у повільному циклі, поки його не буде задоволено.
Vality
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.