Comment empêcher Linux de geler en cas de mémoire insuffisante?

25

Aujourd'hui, j'ai (accidentellement) exécuté un programme sur ma machine Linux qui a rapidement utilisé beaucoup de mémoire. Mon système a gelé, est devenu insensible et je n'ai donc pas pu tuer le délinquant.

Comment puis-je empêcher cela à l'avenir? Ne peut-il pas au moins garder un noyau réactif ou quelque chose en cours d'exécution?

johv
la source
Duplicate of System se bloque lorsqu'il manque de mémoire , et c'est un bug
Dan Dascalescu

Réponses:

15

Je parie que le système n'a pas vraiment "gelé" (dans le sens où le noyau s'est bloqué), mais qu'il ne répondait tout simplement pas. Il y a de fortes chances qu'il soit simplement échangé très fort, provoquant une baisse des performances interactives et du débit du système comme une pierre.

Vous pouvez désactiver le swap, mais cela ne fait que changer le problème des performances médiocres aux processus tués par OOM (et tout le plaisir qui en découle), ainsi que des performances réduites en raison du moins de cache disque disponible.

Alternativement, vous pouvez utiliser des limites de ressources par processus (communément appelées rlimitet / ou ulimit) pour éliminer la possibilité qu'un seul processus prenne une quantité ridicule de mémoire et provoque un échange, mais cela vous pousse simplement à vous divertir avec des processus qui meurent à moments gênants car ils voulaient un peu plus de mémoire que le système ne voulait leur en donner.

Si vous saviez que vous alliez faire quelque chose susceptible d'entraîner une utilisation massive de la mémoire, vous pourriez probablement écrire un programme wrapper qui a fait mlockall()et exécuté votre shell; cela le garderait en mémoire et serait la chose la plus proche de "garder un noyau réactif" que vous obtiendrez probablement (car ce n'est pas que le processeur est surutilisé qui est le problème).

Personnellement, je souscris à la méthode de contrôle des ressources «ne fais pas de bêtises». Si vous avez un root, vous pouvez endommager un système de toutes sortes, et ainsi faire tout ce dont vous ne connaissez pas les résultats probables est une entreprise risquée.

womble
la source
2
Malheureusement, «ne faites pas de bêtises» n'aide pas les utilisateurs qui exécutent des applications de mémoire mémoire comme Chrome (voir les problèmes 134612 , 393395 ).
Dan Dascalescu
1
@DanDascalescu Et il n'est pas toujours évident que vous faites quelque chose de stupide. Ma machine s'est bloquée l'autre jour parce que j'ai changé un "UNION" dans une requête SQLite (compliquée) en "UNION ALL".
Michael
Les programmes de bogues connus peuvent (et devraient) être exécutés dans une configuration limitée par les ressources - ulimit, ou même les groupes de discussion de nos jours, si vous êtes un jeune branché, fait très bien le travail. Si vous apportez des modifications aux requêtes en production sans valider leurs effets dans un environnement non critique, c'est votre problème d'origine.
womble
8

Comme mentionné ci-dessus dans le commentaire de Tronic, il est possible d'appeler OOM-killer (out of memory killer) directement par la combinaison de clavier SysRq- F.

SysRqla touche est généralement combinée dans la PrtSctouche sur les claviers.

OOM-killer tue certains processus (-es) et le système redevient réactif. L'accès direct à OOM-killer peut ne pas être activé par défaut, consultez cette question pour savoir comment vérifier son état et / ou l'activer.

PS: Cela m'a beaucoup aidé. Je suis d'accord avec l'opinion que c'est le conseil le plus utile à propos de ce problème s'il est causé par Chrome ou tout autre logiciel gourmand en mémoire. Mais vous devez garder à l'esprit que OOM-killer pourrait tuer un processus vraiment important, utilisez-le avec précaution.

Arkemlar
la source
0

Si vous avez envie de recompiler le noyau, vous pouvez essayer le patch de la EDITsection de cette question: /programming//q/52067753/10239615
Il n'efface pas les Active(file)pages lors d'une forte pression mémoire et permet donc OOM-killer pour se déclencher presque instantanément car le noyau n'a plus besoin de passer des minutes de relecture constante depuis le disque des pages de code exécutables de chaque processus, provoquant un système d'exploitation gelé.


la source
-1

C'est quelque chose de particulièrement difficile à éviter. C'est parce que le noyau commence à échanger. Une solution consiste à désactiver l'échange. Lorsque le système manque de mémoire, plutôt que de commencer à échanger, le noyau va tuer certains processus; généralement, il sélectionne le processus correct à tuer, mais il est de toute façon préférable de tuer un processus aléatoire que d'avoir un système qui ne répond pas.

Cela peut être une solution particulièrement bonne pour les serveurs, car les serveurs ont souvent suffisamment de RAM et lorsqu'ils commencent à utiliser l'espace d'échange, cela signifie que quelque chose ne va pas de toute façon. Cependant, les ordinateurs de bureau ont généralement besoin de l'espace d'échange, donc je pense qu'il n'y a pas de bonne solution pour les ordinateurs de bureau. Je désactive souvent l'espace de swap sur les serveurs, en particulier en cas de suspicion de fuite de mémoire.

Antonis Christofides
la source
4
Désactiver l'échange sur n'importe quel système est une mauvaise idée, car cela ne permet pas d'échanger les pages inutilisées et l'espace libre utilisé pour le cache disque. Cela est particulièrement vrai en cas de fuite de mémoire.
womble
2
Et avec swap off, le système peut encore ralentir en raison de la pagination. Il s'agit simplement de paginer follement des pages propres au lieu de sales. (Puisque, sans échange, il ne peut jamais expulser une page sale, il devra toujours en expulser une propre.)
David Schwartz
J'ai un serveur qui a une fuite de mémoire. La première fois que cela s'est produit, j'ai dû appuyer sur le bouton de réinitialisation, car le serveur ne répondait plus. Mais maintenant que j'ai désactivé le swap, le serveur tue simplement l'enfant apache s'il devient trop grand (c'est une sauvegarde en plus de MaxRequestsPerChild). Le résultat est que le serveur fonctionne sans problème. De toute façon, il n'a pas beaucoup de pages inutilisées et il ne s'agit pas de paginer follement des pages propres.
Antonis Christofides
@AntonisChristofides: Je ne sais pas ce que vous pensez de la leçon à retenir. Votre solution est certainement mauvaise car elle entrave les performances en raison de l'impossibilité d'expulser les pages sales rarement accessibles de la mémoire physique, elle n'a pas résolu le problème sous-jacent et vous courez le risque que le tueur OOM puisse tuer un processus critique. Il vous est arrivé de ne pas rencontrer le danger particulier dont je vous avais parlé, mais vous êtes toujours en danger parce que vous n'avez pas d'échange.
David Schwartz
8
Avec ou sans échange, il se bloque toujours avant que le tueur OOM ne s'exécute automatiquement. Il s'agit vraiment d'un bug du noyau qui devrait être corrigé (c'est-à-dire exécuter OOM killer plus tôt, avant de supprimer tout le cache disque). Malheureusement, les développeurs du noyau et beaucoup d'autres personnes ne voient pas le problème. Les suggestions courantes telles que désactiver / activer l'échange, acheter plus de RAM, exécuter moins de processus, définir des limites, etc. ne résolvent pas le problème sous-jacent que la faible gestion de la mémoire du noyau suce les boules de chameau. En attendant, je suggère d'exécuter le tueur OOM manuellement (SysRq-F) lorsque le système se bloque car cela le fera récupérer plus rapidement.
Tronic