Comment fonctionne vm.overcommit_memory?

50

Quand j'utilise les paramètres par défaut:

vm.overcommit_memory = 0
vm.overcommit_ratio = 50

Je peux lire ces valeurs du /proc/meminfofichier:

CommitLimit:     2609604 kB
Committed_AS:    1579976 kB

Mais quand je change vm.overcommit_memoryde 0à 2, je suis incapable de démarrer le même ensemble d'applications que je pourrais commencer avant le changement, en particulier amarok. Je devais changer vm.overcommit_ratiopour 300que la limite puisse être augmentée. Maintenant, quand je commence amarok, /proc/meminfomontre ce qui suit:

CommitLimit:     5171884 kB
Committed_AS:    3929668 kB

Cette machine ne dispose que de 1 Go de RAM, mais amarok fonctionne sans problème quand vm.overcommit_memoryest défini sur 0. Mais dans le cas de la configuration sur 2, amarok doit allouer plus de 2 Go de mémoire. Est-ce un comportement normal? Si tel est le cas, quelqu’un pourrait-il expliquer pourquoi, par exemple, firefox (qui consomme 4 à 6 fois plus de mémoire que amarok) fonctionne de la même manière avant et après le changement?

Mikhail Morfikov
la source

Réponses:

67

Vous pouvez trouver la documentation dans man 5 proc( ou sur kernel.org ):

/proc/sys/vm/overcommit_memory
       This file contains the kernel virtual memory accounting mode.
       Values are:

              0: heuristic overcommit (this is the default)
              1: always overcommit, never check
              2: always check, never overcommit

       In mode 0, calls of mmap(2) with MAP_NORESERVE are not
       checked, and the default check is very weak, leading to the
       risk of getting a process "OOM-killed".

       In mode 2 (available since Linux 2.6), the total virtual
       address space that can be allocated (CommitLimit in /proc/mem‐
       info) is calculated as

           CommitLimit = (total_RAM - total_huge_TLB) *
                         overcommit_ratio / 100 + total_swap

La réponse simple est que, si vous définissez un excédent de fonds sur 1, vous créez la scène de sorte que, lorsqu'un programme appelle quelque chose comme malloc()pour allouer un bloc de mémoire ( man 3 malloc), il réussira toujours, que le système sache qu'il n'aura pas toute la mémoire en cours. demandé.

Le concept sous-jacent à comprendre est l'idée de mémoire virtuelle . Les programmes voient un espace d'adressage virtuel mappé ou non sur la mémoire physique réelle. En désactivant la vérification de surcapacité, vous indiquez au système d'exploitation de supposer qu'il y a toujours assez de mémoire physique pour sauvegarder l'espace virtuel.

Exemple

Pour souligner pourquoi cela peut parfois être important, jetez un coup d'œil aux recommandations de Redis sur la raison pour laquelle vm.overcommit_memoryil convient de définir le paramètre sur 1.

Kyle Brandt
la source
2
Mais la valeur de ne devrait-elle pas Committed_ASêtre la même dans les deux cas?
Mikhail Morfikov
@ MikhailMorfikov: En théorie, je le crois, mais qui sait ce que font ces programmes? Voudrait voir un environnement plus contrôlé avec un programme simple qui alloue juste un gig de ram via Malloc. Et puis exécutez le test après le redémarrage entre les tests.
Kyle Brandt
Ok, je vais rester avec 0pour l'instant.
Mikhail Morfikov
2
@ MikhailMorfikov: Oui, pratiquement, je pense que 0 est le plus logique. Dans mon environnement, le seul moment où j'active 1 concerne Redis, qui effectue des tâches pour lesquelles il s'attend à demander beaucoup plus de mémoire qu'il utilise en raison d'un fork (). L'enfant utilisera à peu près toutes les mêmes pages de mémoire, mais Linux ne sait pas qui dit qu'il faut être sûr qu'il devra utiliser 2x (si vous voulez en savoir plus: redis.io/topics/faq )
Kyle Brandt
La dernière affirmation de votre réponse ne devrait-elle pas commencer par "en activant le sur-engagement"? parce que le mettre à 1 signifie que vous lui demandez de sur-engager, non?
Asgs