web-dev-qa-db-fra.com

Comment fonctionne vm.overcommit_memory?

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

vm.overcommit_memory = 0
vm.overcommit_ratio = 50

Je peux lire ces valeurs depuis /proc/meminfo fichier:

CommitLimit:     2609604 kB
Committed_AS:    1579976 kB

Mais quand je change vm.overcommit_memory de 0 à 2, Je ne peux pas démarrer le même ensemble d'applications que je pouvais démarrer avant le changement, en particulier amarok. Je devais changer vm.overcommit_ratio à 300, afin que la limite puisse être augmentée. Maintenant, quand je commence amarok, /proc/meminfo montre ce qui suit:

CommitLimit:     5171884 kB
Committed_AS:    3929668 kB

Cette machine n'a que 1 Go de RAM, mais amarok fonctionne sans problème lorsque vm.overcommit_memory est défini sur 0. Mais dans le cas où il est défini sur 2, amarok doit allouer plus de 2 Go de mémoire. Est-ce un comportement normal? Dans l'affirmative, 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?

52
Mikhail Morfikov

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 est simple: si vous définissez overcommit sur 1, la scène sera mise en place de sorte que lorsqu'un programme appelle quelque chose comme malloc() pour allouer un morceau de mémoire (man 3 malloc), Il réussira toujours, peu importe si le système sait qu'il n'aura pas toute la mémoire demandée.

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

Exemple

Pour souligner pourquoi cela peut parfois avoir de l'importance, jetez un œil aux Redis guidances pourquoi vm.overcommit_memory Devrait être mis à 1 pour cela.

72
Kyle Brandt

C'est une vieille question avec une réponse bien établie, mais je pense qu'il y a plus à ajouter.

Tout d'abord, lorsque vm.overcommit_memory = 0, le vm.overcommit_ratio la valeur n'est pas pertinente. Le noyau utilisera un algorithme heuristique pour surcharger la mémoire, afin que votre processus amarok puisse se voir allouer plus de mémoire que ce qui est disponible.

Lorsque vous définissez vm.overcommit_memory à 2, le vm.overcommit_ratio la valeur devient pertinente. Par défaut, cette valeur est définie sur 50, ce qui signifie que le système n'allouerait que jusqu'à 50% de votre RAM (plus swap). Cela explique pourquoi vous ne pouvez pas démarrer des programmes qui allaient bien lorsque vm.overcommit_memory = 0 - car il y a moins de 500 Mo de mémoire allouable (en supposant qu'il n'y ait pas d'échange).

Lorsque vous le définissez sur 300, vous autorisez le système à allouer jusqu'à 300% de votre RAM (plus swap, le cas échéant), c'est pourquoi la valeur CommitLimit dans /proc/meminfo est tellement élevé.

Bien que vm.overcommit_memory = 2 est généralement utilisé pour éviter le sur-engagement, ici, vous l'utilisez pour plafonner le montant qui peut être sur-engagé. Le définir sur 300 est dangereux car votre système n'a pas 5171884 kB de mémoire, et donc, en fonction de l'espace de swap dont vous disposez, le système utilisera swap (ce qui est lent), ou il n'y aura plus de mémoire.

Quant à savoir pourquoi amarok utilise plus de mémoire lorsque vm.overcommit_memory = 2 - c'est probablement parce que amarok fonctionne mieux avec plus de mémoire, mais aussi avec moins. Ainsi, la logique du programme peut essayer d'allouer initialement 2 Go de mémoire, mais en cas d'échec, essayez 1 Go.

3
d4nyll