éviter le gel / absence de réponse du système en raison de l'utilisation abusive de la mémoire


45

Si un processus nécessite beaucoup de mémoire, le système transfère tous les autres processus dans le fichier d'échange. Y compris, semble-t-il, des processus nécessaires comme le serveur X11 ou le terminal.

Ainsi, si un processus continue à allouer sans limite, tout devient insensible, jusqu'à ce que ce processus soit tué par le destructeur de MOO. Mon ordinateur portable semble être particulièrement sensible et réagit extrêmement mal. Je viens de passer une heure entière à attendre la fin du processus pendant lequel même le curseur de la souris ne pouvait pas être déplacé.

Comment cela peut-il être évité?

1) Désactiver le swap => Je lance souvent beaucoup de processus qui deviennent ensuite inactifs. Les inactifs doivent être déplacés vers l’échange.

2) Obtenez un SSD => trop cher

3) définissez un maximum de mémoire ulimit => mais cela échouera dans les cas où un programme a besoin d'une quantité de mémoire importante et résonable. le problème n'est pas qu'il en utilise trop, mais qu'il supprime les autres processus

4) garder en mémoire les programmes importants (X11, bash, kill, top, ...) et ne jamais les échanger => cela peut-il être fait? Comment? peut-être seulement échanger de gros programmes?

5)?


Et c'est arrivé à nouveau :( Commencé gcc alors que Firefox était en marche, tout était bloqué pendant une demi-heure. Aucun mouvement de souris, aucune lecture de livre électronique
BeniBela

Je ne suis pas sûr de comprendre ce que tu veux. Voulez-vous que le système accélère magiquement avec les ressources dont il dispose? Voulez-vous qu'il tue les processus qui utilisent beaucoup de mémoire plus tôt?
David Schwartz

On dirait que ce dont vous avez vraiment besoin, c'est plus de RAM. Ou moins de tâches en arrière-plan «inactives».
Daniel B

2
Vous pouvez utiliser la combinaison de touches Alt + SysRq + F pour forcer l'exécution du tueur OOM. Cela peut réduire le temps nécessaire à attendre que votre système ouvre une console pour pouvoir arrêter un processus.
hololeap

Corrigez-moi si je me trompe, mais ce problème semble indiquer que le système recherche un espace d'échange de disque qui devrait exister mais n'existe pas (la partition d'échange est trop petite). Si l’espace de permutation est insuffisant, le système "écrase" le disque dur (ou le disque SSD) à la recherche d’espace disponible.
mardi

Réponses:


43

TL; DR

Courte temporaire / réponse

  • Le plus simple : créez une partition de swap plus petite et évitez au noyau d'essayer de croire qu'il n'y a pas de limite de mémoire en exécutant des processus à partir d'un stockage lent.
    • Avec un grand échange, le MOO (gestionnaire de mémoire épuisé) n'agit pas assez tôt. En règle générale, cela correspond à la mémoire virtuelle et, dans mon expérience passée, il n'a pas tué de choses tant que l'échange n'était pas entièrement rempli, d'où le système volumineux et rampant ...
  • Besoin d'un grand échange pour une veille prolongée?
    • Tentative / problématique : Définissez quelques ulimits (par exemple, vérifiez ulimit -v, et peut-être définir une limite ferme ou douce en utilisant l' asoption in limits.conf). Auparavant, cela fonctionnait assez bien, mais grâce à l'introduction de WebKit gigacage, de nombreuses applications gnome s'attendent maintenant à des espaces d'adressage illimités et ne parviennent pas à s'exécuter!
    • Tentative / problématique : La politique de surdimensionnement et le rapport est une autre façon d'essayer de gérer et d' atténuer ce (par exemple sysctl vm.overcommit_memory, sysctl vm.overcommit_ratiomais cette approche n'a pas fonctionné pour moi.
    • Difficile / compliqué : Essayez d’appliquer une priorité de groupe sur les processus les plus importants (par exemple, ssh), mais cela semble actuellement fastidieux pour cgroup v1 (espérons que la version 2 le facilitera) ...

J'ai aussi trouvé:

Solution à plus long terme

attendre et espérer que certains correctifs en amont pénètrent dans les noyaux distro stables. Espérons également que les fournisseurs de distribution améliorent les valeurs par défaut du noyau et exploitent mieux les groupes de contrôle systemd pour hiérarchiser la réactivité de l’interface graphique dans les éditions de bureau.

Quelques taches d'intérêt:

Donc, ce n’est pas seulement le mauvais code d’espace utilisateur et la configuration / configuration par défaut de la distribution qui sont en cause - le noyau pourrait mieux gérer cela.

Commentaires sur les options déjà envisagées

1) Désactiver l'échange

Il est recommandé de fournir au moins une petite partition de swap ( Avons-nous vraiment besoin de swap sur les systèmes modernes? ). Désactiver le swap empêche non seulement le remplacement des pages inutilisées, mais peut également affecter la stratégie de surcommission heuristique par défaut du noyau pour l'allocation de mémoire ( Que signifie l'heuristique dans Overcommit_memory = 0? ), Cette heuristique comptant sur les pages d'échange. Sans échange, le sur-engagement peut toujours fonctionner dans les modes heuristique (0) ou toujours (1), mais la combinaison de l’absence de permutation et de la stratégie de non-dépassement jamais (2) est probablement une idée terrible. Dans la plupart des cas, aucun échange ne sera donc préjudiciable aux performances.

Par exemple, pensez à un long processus qui commence par toucher la mémoire pour un travail ponctuel, mais ne parvient pas à libérer cette mémoire et continue à exécuter l'arrière-plan. Le noyau devra utiliser de la RAM jusqu'à la fin du processus. Sans aucun échange, le noyau ne peut pas le rechercher pour quelque chose d'autre qui veut réellement utiliser activement la RAM. Pensez également au nombre de développeurs qui sont paresseux et ne libérez pas explicitement la mémoire après utilisation.

3) définir une mémoire ulimit maximale

Cela ne s'applique que par processus, et il est probablement raisonnable de penser qu'un processus ne devrait pas demander plus de mémoire qu'un système possède physiquement! Il est donc probablement utile d’empêcher un processus isolé et fou de déclencher des raclées tout en restant généreux.

4) garder en mémoire les programmes importants (X11, bash, kill, top, ...) et ne jamais les échanger

Bonne idée, mais alors ces programmes auront une mémoire qu'ils ne sont pas en train d'utiliser. Cela peut être acceptable si le programme ne demande qu'une petite quantité de mémoire.

La version 232 de systemd vient d'ajouter quelques options qui rendent cela possible: je pense que l'on pourrait utiliser "MemorySwapMax = 0" pour empêcher une unité (service) telle que ssh de perdre de la mémoire.

Néanmoins, pouvoir hiérarchiser l’accès à la mémoire serait mieux.

Longue explication

Le noyau linux étant mieux adapté aux charges de travail du serveur, la réactivité de l'interface graphique a malheureusement été une préoccupation secondaire ... Les paramètres de gestion de la mémoire du noyau dans l'édition Desktop d'Ubuntu 16.04 LTS ne semblaient pas différer de ceux des autres éditions de serveur. Il correspond même aux valeurs par défaut de RHEL / CentOS 7.2, généralement utilisé en tant que serveur.

MOO, ulimit et compromis de l'intégrité pour la réactivité

Le swap thrashing (lorsque le jeu de mémoire de travail, c'est-à-dire les pages en cours de lecture et d'écriture dans un laps de temps donné supérieur à la RAM physique) verrouille toujours le stockage en entrée / sortie - aucune magie du noyau ne peut enregistrer un système sans tuer un processus ou deux...

J'espère que les modifications mineures de la MOO Linux apparaissant dans les noyaux plus récents reconnaîtront que cet ensemble de travail dépasse la situation de mémoire physique et met fin à un processus. Quand ce n'est pas le cas, le problème se produit. Le problème est que, avec une grande partition de swap, il peut sembler que le système a encore une marge de sécurité alors que le noyau s’engage joyeusement et continue de servir les demandes de mémoire, mais l’ensemble de travail peut déborder dans le swap, essayant effectivement de traiter le stockage comme si c'est RAM.

Sur les serveurs, il accepte la pénalité de performances de la course pour un temps déterminé, lent, ne perdez pas de données, un compromis. Sur les ordinateurs de bureau, le compromis est différent et les utilisateurs préfèrent un peu de perte de données (sacrifice de processus) pour que les choses restent réactives.

C'était une belle analogie comique à propos de MOO: oom_pardon, alias ne tuez pas mon xlock

Incidemment, il OOMScoreAdjustexiste une autre option systemd pour aider à peser et éviter les processus de destruction de MOO considérés comme plus importants.

écriture différée en mémoire tampon

Je pense que " Rendre l'écriture en arrière-plan non sucer " aidera à éviter certains problèmes dans lesquels un processus de pagaille RAM provoque un autre échange (écriture sur disque) et que l'écriture en bloc sur disque bloque tout ce qui veut IO. Ce n'est pas le problème de la cause, mais il ajoute à la dégradation globale de la réactivité.

ulimits limitation

Un problème avec ulimits est que la limite de comptabilisation et d'application s'applique à l'espace d'adressage de la mémoire virtuelle (ce qui implique la combinaison de l'espace physique et de l'espace de permutation). Selon man limits.conf:

       rss
          maximum resident set size (KB) (Ignored in Linux 2.4.30 and
          higher)

Donc, configurer un ulimit pour l'appliquer uniquement à l'utilisation de la RAM physique ne semble plus utilisable. Par conséquent

      as
          address space limit (KB)

semble être le seul accordable respecté.

Malheureusement, comme expliqué plus en détail dans l'exemple de WebKit / Gnome, certaines applications ne peuvent pas s'exécuter si l'allocation d'espace d'adressage virtuel est limitée.

Les groupes de discussion devraient aider à l'avenir?

Actuellement, cela semble fastidieux, mais il est possible d'activer certains drapeaux du groupe de cgroup_enable=memory swapaccount=1contrôle du noyau (par exemple, dans la configuration grub), puis d'essayer d'utiliser le contrôleur de mémoire du groupe de contrôle cgroup pour limiter l'utilisation de la mémoire.

Les groupes de contrôle ont des fonctionnalités de limite de mémoire plus avancées que les options 'ulimit'. Les notes de CGroup v2 suggèrent des tentatives d’amélioration du fonctionnement d’ulimits.

La combinaison mémoire + échange et limitation est remplacée par un contrôle réel sur l’espace de swap.

Les options du groupe peuvent être définies via les options de contrôle des ressources systemd . Par exemple:

  • MémoireHigh
  • MemoryMax

D'autres options utiles pourraient être

  • IOWeight
  • CPUShares

Ceux-ci ont des inconvénients:

  1. Aérien. La documentation actuelle de docker mentionne brièvement 1% d'utilisation de mémoire supplémentaire et 10% de dégradation des performances (probablement en ce qui concerne les opérations d'allocation de mémoire - cela ne spécifie pas vraiment).
  2. Les choses concernant Cgroup / systemd ont été considérablement retravaillées récemment, de sorte que le flux en amont implique que les fournisseurs de distribution Linux attendent peut-être d’être réglés en premier.

Dans CGroup v2 , ils suggèrent que cela memory.highdevrait être une bonne option pour limiter et gérer l'utilisation de la mémoire par un groupe de processus. Cependant, cette citation suggère que la surveillance des situations de pression de la mémoire nécessitait davantage de travail (à partir de 2015).

Une mesure de la pression de la mémoire - à quel point la charge de travail est affectée par un manque de mémoire - est nécessaire pour déterminer si une charge de travail a besoin de plus de mémoire; Malheureusement, le mécanisme de surveillance de la pression de la mémoire n'est pas encore implémenté.

Etant donné que les outils d'espace utilisateur systemd et cgroup sont complexes, je n'ai pas trouvé de moyen simple de définir quelque chose de approprié et de l'exploiter davantage. La documentation de cgroup et systemd pour Ubuntu n’est pas excellente. Les travaux futurs devraient concerner les distributions avec les éditions de bureau afin de tirer parti de cgroups et systemd de manière à ce que ssh et les composants X-Server / gestionnaire de fenêtres obtiennent un accès plus prioritaire à la CPU, à la RAM physique et aux E / S de stockage, afin d'éviter la concurrence avec les processus. occupé à permuter. Les fonctions de priorité du processeur et des E / S du noyau existent depuis un moment. Il semble que l'accès prioritaire à la mémoire RAM physique manque.

Cependant, même les priorités du processeur et des E / S ne sont pas correctement définies!? Quand j'ai vérifié les limites de cdd de systemd, les parts de cpu, etc. appliquées, autant que je sache, Ubuntu n'avait pas cuit dans une priorisation prédéfinie. Par exemple, j'ai couru:

systemctl show dev-mapper-Ubuntu\x2dswap.swap

J'ai comparé cela à la même sortie pour ssh, samba, gdm et nginx. Des éléments importants tels que l'interface graphique et la console d'administration distante doivent se battre de manière égale avec tous les autres processus en cas de blocage.

Exemple de limites de mémoire que j'ai sur un système de 16 Go de RAM

Je voulais activer l'hibernation, j'avais donc besoin d'une grande partition de swap. D'où la tentative d'atténuer avec ulimits, etc.

ulimit

J'ai mis * hard as 16777216en /etc/security/limits.d/mem.conftelle qu'aucun processus ne serait autorisé à demander plus de mémoire que physiquement possible. Je n'empêcherai pas les combats tous ensemble, mais sans cela, un seul processus utilisant une mémoire gourmande, ou une fuite de mémoire, peut provoquer des contournements. Par exemple, j'ai vu gnome-contactsaccumuler plus de 8 Go de mémoire lors de tâches banales telles que la mise à jour de la liste d'adresses globale à partir d'un serveur Exchange ...

Gnome en train de mâcher de la RAM

Comme on peut le voir ulimit -S -v, de nombreuses distributions ont cette limite stricte et souple définie comme étant «illimitée», en théorie, un processus pourrait demander beaucoup de mémoire, mais uniquement utiliser activement un sous-ensemble, et fonctionner avec bonheur en pensant qu'il dispose de 24 Go de RAM, le système n'a que 16 Go. La limite stricte ci-dessus entraînera l'abandon des processus qui auraient pu s'exécuter correctement lorsque le noyau refuse leurs demandes de mémoire spéculative gloutonne.

Cependant, il intercepte également des choses insensées comme les contacts de gnome et au lieu de perdre la réactivité de mon bureau, je reçois l’erreur "pas assez de mémoire libre":

entrez la description de l'image ici

Complications posant ulimit pour l'espace d'adressage (mémoire virtuelle)

Malheureusement, certains développeurs prétendent que la mémoire virtuelle est une ressource infinie et définir ulimit sur de la mémoire virtuelle peut endommager certaines applications. Par exemple, WebKit (dont dépendent certaines applications gnome) a ajouté une gigacagefonctionnalité de sécurité qui tente d’allouer une quantité insensée de mémoire virtuelle. Des FATAL: Could not allocate gigacage memoryerreurs avec un soupçon effronté Make sure you have not set a virtual memory limitse produisent. Le work-around,GIGACAGE_ENABLED=norenonce aux avantages en matière de sécurité, mais de même, ne pas être autorisé à limiter l’allocation de mémoire virtuelle, c’est aussi renoncer à un élément de sécurité (par exemple, un contrôle des ressources pouvant empêcher un déni de service). Ironiquement, entre gigacage et les développeurs gnome, ils semblent oublier que limiter l’allocation de mémoire est en soi un contrôle de sécurité. Et malheureusement, j'ai remarqué que les applications gnome qui reposent sur le gigacage ne demandent pas explicitement une limite supérieure, de sorte que même une limite souple casse les choses dans ce cas.

Pour être juste, si le noyau réussissait mieux à refuser l'allocation de mémoire basée sur l'utilisation de la mémoire résidente au lieu de la mémoire virtuelle, prétendre que la mémoire virtuelle est illimitée serait moins dangereux.

surconsommer

Si vous préférez que les applications se voient refuser l'accès à la mémoire et que vous ne vouliez plus en faire, utilisez les commandes ci-dessous pour tester le comportement de votre système lorsqu'il est soumis à une pression de mémoire élevée.

Dans mon cas, le taux de validation par défaut était:

$ sysctl vm.overcommit_ratio
vm.overcommit_ratio = 50

Mais cela ne prend effet que lorsque vous modifiez la stratégie pour désactiver le sur-engagement et appliquer le ratio.

sudo sysctl -w vm.overcommit_memory=2

Le ratio implicite ne pouvait allouer que 24 Go de mémoire au total (16 Go de RAM * 0,5 + 16 Go SWAP). Par conséquent, je ne verrais probablement jamais jamais apparaître un MOO, et il serait effectivement moins probable que des processus accèdent constamment à la mémoire lors de l'échange. Mais je vais probablement aussi sacrifier l'efficacité globale du système.

Cela provoquera le blocage de nombreuses applications, étant donné qu'il est courant que les développeurs gèrent mal le système d'exploitation refusant une demande d'allocation de mémoire. Il réduit le risque occasionnel de blocage important dû à des coups (de perdre tout votre travail après une réinitialisation matérielle) à un risque plus fréquent de blocage de diverses applications. Lors de mes tests, cela n'a pas beaucoup aidé, car le poste de travail lui-même est tombé en panne lorsque le système était sous pression mémoire et qu'il ne pouvait pas allouer de mémoire. Cependant, au moins les consoles et SSH fonctionnaient toujours.

Comment le travail de mémoire surchargée de VM a plus d’informations.

J'ai choisi de revenir aux valeurs par défaut pour cela, sudo sysctl -w vm.overcommit_memory=0étant donné que la pile graphique du bureau et les applications qui s'y trouvent tombent toujours en panne.


3
C’est le meilleur article que j’ai vu sur le sujet, et vous n’avez pas recours à "achetez simplement plus de RAM!" Une chose que vous ne mentionnez pas est la façon dont les options de configuration du noyau jouent dans cela. Par exemple, le modèle de pré-utilisation utilisé ou le planificateur d'E / S utilisé aurait-il un impact majeur sur cette situation?
hololeap

2
but the kernel won't be able to use an overcommit strategy for allocating memory and this will likely hurt performance. Even a smaller swap partition allows this. Y at-il une preuve à cela? Je crois que le noyau sur-effectue très bien sans échange configuré
ygrek le

@ygrek, merci, cette formulation a l'air un peu fausse - le sur-engagement fonctionne toujours sans échange, à moins que le mode jamais de sur-engagement (2) ne soit choisi. Le mode de surimplication heuristique par défaut (0) ou les modes toujours de validation (1) fonctionnent probablement toujours sans échange. Je ne me souviens plus où j'ai lu que désactiver le swap bloque la capacité du code à surconsommation à allouer de la mémoire (et le mode qu'il affecte spécifiquement). Googlé à nouveau sans chance, mais c'était un post semi-utile: stackoverflow.com/questions/38688824/… Je vais modifier la réponse de manière appropriée.
JPvRiel

J'espérais que le correctif d'écriture en arrière-plan m'aiderait, mais je suis sur un tout nouveau noyau (4.14.81) et je suis confronté à des problèmes de réactivité considérables sous un disque dur d'E / S (que l'échange soit la cause ou non). Je me demande si le gestionnaire de périphériques ou mon chiffrement LUKS pose des problèmes de performances. J'ai vraiment aucune idée de comment déboguer ce genre de problème.
Darius Jahandarie
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.