La section 9.6 "Surcommission et MOO" dans la documentation mentionnée par @dunxd est particulièrement graphique sur les dangers de permettre une sur-utilisation. Cependant, cela 80
m’intéressait aussi et j’ai donc fait quelques tests.
Ce que j'ai trouvé, c'est que cela overcommit_ratio
affecte la RAM totale disponible pour TOUS les processus. Les processus racine ne semblent pas être traités différemment des processus utilisateur normaux.
Fixer le ratio à 100
ou moins devrait fournir la sémantique classique pour laquelle les valeurs renvoyées malloc/sbrk
sont fiables. Définir des ratios inférieurs à ce qui 100
pourrait être un moyen de réserver plus de RAM pour des activités non liées au processus telles que la mise en cache, etc.
Donc, sur mon ordinateur avec 24 Go de RAM, avec permutation désactivée, 9 Go en cours d'utilisation, avec top
affichage
Mem: 24683652k total, 9207532k used, 15476120k free, 19668k buffers
Swap: 0k total, 0k used, 0k free, 241804k cached
Voici quelques overcommit_ratio
paramètres et la quantité de RAM que mon programme consommateur-ram peut prendre (en touchant chaque page) - dans chaque cas, le programme est sorti proprement une fois en malloc
échec.
50 ~680 MiB
60 ~2900 MiB
70 ~5200 MiB
100 ~12000 MiB
En exécuter plusieurs à la fois, même si certains en sont l'utilisateur root, n'a pas modifié la quantité totale consommée ensemble. Il est intéressant de noter qu’il n’a pas été en mesure de consommer les 3 derniers GiB ou plus; le free
n'a pas chuté beaucoup en dessous de ce qui est montré ici:
Mem: 24683652k total, 20968212k used, 3715440k free, 20828k buffers
Les expériences étaient désordonnées - tout ce qui utilise malloc au moment où toute la RAM est utilisée a tendance à planter, car de nombreux programmeurs ne savent pas comment vérifier les échecs de malloc en C, certaines bibliothèques de collections populaires l'ignorent entièrement, et C ++ et d'autres langages le sont également. pire.
La plupart des premières implémentations de RAM imaginaire que j'ai vues concernaient un cas très spécifique, dans lequel un seul processus volumineux - disons 51% + de mémoire disponible - était nécessaire pour pouvoir mettre fork()
en place exec()
un programme de support, généralement beaucoup plus petit. Les systèmes d'exploitation avec une sémantique de copie sur écriture le permettent fork()
, mais à condition que si le processus forké tente réellement de modifier trop de pages mémoire (chacune d'entre elles devrait ensuite être instanciée comme une nouvelle page indépendante du processus énorme initial) il finirait par se faire tuer. Le processus parent n'était en danger que si l'on allouait plus de mémoire et pouvait gérer l'épuisement des stocks, dans certains cas, il suffisait d'attendre un peu qu'un autre processus meure, puis de continuer. Le processus enfant vient généralement de se remplacer par un programme (généralement plus petit) viaexec()
et était alors libre de la condition.
Le concept de surengagement de Linux est une approche extrême permettant à la fois fork()
de se produire et de permettre à des processus uniques d’alléger massivement. Décès causés OOM-tueuses se produisent de manière asynchrone, même aux programmes qui font la poignée allocation de mémoire de façon responsable. Personnellement, je déteste la surcharge de travail à l’ échelle du système en général et celle de l’Oom-killer en particulier - elle favorise une approche diabolique de la gestion de la mémoire qui infecte les bibliothèques et, par leur intermédiaire, toutes les applications qui les utilisent.
Je suggèrerais de fixer le rapport à 100 et d’avoir également une partition de swap qui ne serait généralement utilisée que par d’énormes processus - qui utilisent souvent une infime fraction de la partie de leur vie qui est bourrée dans le swap, et donc protéger la grande majorité des processus du mauvais fonctionnement du tueur OOM. Cela devrait garder votre serveur Web à l'abri d'une mort aléatoire, et s'il a été écrit pour le gérer de manière malloc
responsable, même s'il ne risque pas de se tuer (mais ne pariez pas sur ce dernier).
Cela signifie que je l'utilise dans /etc/sysctl.d/10-no-overcommit.conf
vm.overcommit_memory = 2
vm.overcommit_ratio = 100