Pourquoi QEMU ne peut-il pas allouer de la mémoire si les caches Linux sont trop gros?

9

Si j'utilise ma machine [Ubuntu 16.04 64 bits, noyau 4.4] pendant un certain temps, QEMU a besoin que les caches du noyau soient supprimés, sinon, il n'arrivera pas à allouer la RAM.

Pourquoi cela arrive-t-il?

Voici un exemple d'exécution:

~$ 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
Marcus
la source
4
Parce que vous n'avez aucun échange.
Michael Hampton,

Réponses:

19

Toutes les données mises en cache ne peuvent pas être supprimées immédiatement. Par exemple, les pages sales mises en cache doivent être réécrites sur le disque avant de pouvoir être supprimées de la RAM. Vous n'avez aucun échange, donc jusqu'à ce que ces écritures soient terminées, il n'y a tout simplement pas assez d'espace disponible pour QEMU.

Vous devriez vraiment ajouter une quantité raisonnable de swap. Vous ne pouvez pas vous attendre à ce que le gestionnaire de mémoire fasse du bon travail avec une main attachée derrière le dos.

David Schwartz
la source
1
En tant que question théorique (puisque j'aimerais en savoir plus sur le fonctionnement de la gestion de la mémoire), pourquoi le gestionnaire ne peut-il pas retarder (bloquer) les tentatives d'allocation de mémoire de QEMU pendant que les pages sales sont en cours de réécriture?
nanofarad
2
@hexafraction Juste une supposition: c'est probablement techniquement possible (mais cela pourrait ajouter une complexité importante, pas sûr), mais les développeurs du noyau diraient probablement que cette fonctionnalité n'est pas nécessaire, car le seul problème qu'elle résout est causé par le fait de ne pas avoir d'échange, ce qui provoque également d'autres problèmes, qui sont tous résolus si vous activez simplement le swap et laissez le noyau gérer sa mémoire comme il est déjà codé pour bien fonctionner.
mtraceur
1
@hexafraction Le noyau n'a aucune idée que c'est une chose sensée à faire. Pour certaines applications, cela n'a aucun sens, ce n'est donc pas la politique générale. QEMU a choisi de ne pas le faire.
David Schwartz
2
@hexafraction Voudriez-vous vraiment attendre 30 secondes - ou plusieurs minutes - pour que votre malloc()appel trouve peut-être suffisamment de mémoire?
Michael Hampton
3
@hexafraction Pensez-y de cette façon. Si le noyau avait théoriquement cette fonctionnalité pour bloquer un certain temps si un malloc échouait autrement, il n'y aurait aucun moyen d'obtenir le comportement actuel sans API supplémentaires. D'un autre côté, l'implémentation actuelle permet à un logiciel qui veut attendre et réessayer un certain temps de réessayer malloc dans une boucle lente jusqu'à ce qu'il soit satisfait.
Vality du