Ubuntu manque rapidement de mémoire vive et mon ordinateur commence à geler. Quelle commande va résoudre ce problème?

73

Cela me arrive assez souvent lorsque je compile un logiciel en arrière-plan et soudain, tout commence à ralentir et finit par geler [si je ne fais rien], car je n'ai plus assez de RAM et d'espace d'échange.

Cette question suppose que je dispose de suffisamment de temps et de ressources pour ouvrir Gnome Terminal, parcourir mon historique et exécuter une sudocommande.

Quelle commande peut m'aider à ne pas avoir à effectuer un redémarrage brutal, ou un redémarrage quelconque?

Akiva
la source
Les commentaires ne sont pas pour une discussion prolongée; cette conversation a été déplacée pour discuter .
Thomas Ward
1
Si vous manquez d'espace d'échange, je pense que vous en avez trop peu. J'ai 20G d'espace swap sur cet ordinateur. Le but est que cela vous donne suffisamment de temps avec un système utilisable pour tuer tout ce qui consume votre mémoire. Ce n'est pas quelque chose où vous prenez seulement ce que vous allez utiliser, mais ce que vous espérez ne jamais utiliser.
JoL
1
Êtes-vous sûr que la RAM et le swap sont remplis? Si tel était le cas, le gestionnaire de MOO tuerait votre compilateur et libérerait de la mémoire (et gâcherait également votre processus de génération). Sinon, je pense que le système est en train de se remplir, et peut-être que votre système est lent car votre échange est sur votre disque système.
sudo
3
Essayez de réduire le nombre de vos constructions parallèles si vous n’avez pas assez de RAM pour la prendre en charge. Si votre build commence à être échangé, vous serez beaucoup plus lent. Avec make, essayez -j4par exemple pour 4 constructions parallèles à la fois.
Shahbaz
1
"Alexa commande moi 8 gigs de ram"

Réponses:

84

D'après mon expérience, Firefox et Chrome utilisent plus de RAM que mes 7 premiers ordinateurs combinés. Probablement plus que cela, mais je m'éloigne de mon propos. La première chose à faire est de fermer votre navigateur . Une commande?

killall -9 firefox google-chrome google-chrome-stable chromium-browser

J'ai lié les navigateurs les plus populaires dans une seule commande, mais évidemment, si vous utilisez quelque chose d'autre (ou savez que vous n'en utilisez aucune), modifiez simplement la commande. Le killall -9 ...est le bit important. Les gens ont peur du SIGKILLsignal 9, mais les navigateurs sont extrêmement résilients. Plus que cela, mettre fin lentement via SIGTERMsignifiera que le navigateur effectuera une charge de nettoyage - ce qui nécessite une rafale de RAM supplémentaire - et c'est quelque chose que vous ne pouvez pas vous permettre dans cette situation.

Si vous ne parvenez pas à insérer cela dans un terminal déjà en marche ou dans un dialogue Alt+ F2, envisagez de passer à un téléscripteur. Control+ Alt+ F2vous amènera à TTY2, ce qui devrait vous permettre de vous connecter (même si cela peut être lent) et devrait même vous permettre d'utiliser quelque chose comme htoppour déboguer le problème. Je ne pense pas avoir déjà manqué de RAM au point de ne pas pouvoir me htoplever.

La solution à long terme consiste à acheter plus de RAM, à la louer via un ordinateur distant ou à ne pas faire ce que vous faites actuellement. Je vous laisse les arguments économiques complexes, mais en règle générale, la RAM n’est pas chère, mais si vous n’avez besoin que d’un montant en rafale, un serveur VPS facturé à la minute ou à l’heure est un bon choix.

Oli
la source
Les commentaires ne sont pas pour une discussion prolongée; cette conversation a été déplacée pour discuter .
Thomas Ward
J'ai quelques commandes liées à ma propre lazygitcommande que j'utilise de temps en temps, peut-être que quelque chose comme ça pourrait être appliquée ici? L'ensemble du killall ...script pourrait être réduit à un simple emptyramou quelque chose comme ça
Francisco Presencia
Vous n'avez pas besoin d'exécuter la commande complète si vous savez quel navigateur est en cours d'exécution et je suppose que la plupart des personnes pouvant identifier une pénurie de RAM le savent. Par extension, je trouverais plus difficile de me rappeler que j'avais écrit un emptyramscript plutôt que de me pointer dedans killall -9 firefox.
Oli
2
Acheter de la RAM ... pourquoi ne pas télécharger plus de RAM?
Stephan Bijzitter
1
Vous risquez de plaisanter, mais si vous avez besoin de faire quelque chose pour un court laps de temps qui nécessite beaucoup plus de RAM et de CPU que vous avez, louer un VPS à la minute devient assez économique pour un one-shot.
Oli
66

Sur un système sur lequel la clé de demande système Magic est activée, une pression sur Alt + System Request+ f(si elle n'est pas marquée sur votre clavier, System Requestest souvent sur la Print Screentouche) invoquera manuellement le tueur de mémoire insuffisante du noyau (oomkiller), qui essaiera de sélectionner le processus incriminé le plus dommageable. utilisation de la mémoire et le tuer. Vous pouvez le faire si vous avez peut-être moins de temps que ce que vous avez décrit et que le système est sur le point de commencer (ou a peut-être déjà commencé) à raser - dans ce cas, vous ne vous souciez probablement pas de ce qui est tué, mais simplement de la fin avec un système utilisable. Parfois, cela peut finir par tuer X, mais la plupart du temps ces jours-ci, il est beaucoup plus efficace de choisir un mauvais processus qu’il ne l’était.

Muzer
la source
5
@ T.Sar, si vous allez directement dans la course, vous perdez déjà ou vous avez une chance de tuer le mangeur de mémoire. Vous ne gagnez rien si vous vous abstenez d'agir.
Ruslan
4
@Muzer cela ne fonctionnera que lorsque vous avez défini kernel.sysrqà 1ou un numéro compris le dans votre peu correcte /etc/sysctl.d/10-magic-sysrq.conf.
Ruslan
9
@ T.Sar Vous ne perdrez pas votre progression si vous utilisez un système de construction rationnel. Vous conserverez tous les fichiers objet, à l'exception de celui que vous étiez en train de compiler, puis vous retournerez à peu près là où vous l'avez laissé.
Muzer
3
@ T.Sar Ce n'est pas parce que ce que vous compilez que vous compilez que le système de construction ne l'est pas. Construire des systèmes depuis des temps immémoriaux ont stocké des fichiers objet pour une utilisation ultérieure dans des compilations. Par ailleurs, je peux certainement nommer de nombreux projets logiciels moins intelligents que Linux (qui est généralement assez bien conçu). Par exemple, en compilant quelque chose comme Firefox ou OpenOffice avec 8 threads de construction parallèles, je peux facilement le voir prendre en ordre de gigaoctets de RAM. Il existe également de nombreux systèmes monolithiques d'entreprise qui dépendent de centaines de bibliothèques.
Muzer
7
@ T.Sar Linux n'est pas vraiment complexe du point de vue du compilateur. En réalité, il n’existe pratiquement aucun programme C. Qu'en est-il du C ++? Avez-vous déjà essayé de créer un programme utilisant Eigen ou Boost? Vous seriez surpris de la quantité de mémoire que le compilateur consomme parfois avec de tels programmes - et ils ne doivent pas nécessairement être complexes eux-mêmes.
Ruslan
20

Contrairement à d’autres réponses, je vous suggère de désactiver le swap en même temps. Bien que l'échange permette au système de fonctionner de manière prévisible et soit souvent utilisé pour augmenter le débit des applications accédant au disque (en évacuant les pages inutilisées pour laisser de la place pour le cache disque), dans ce cas, il semble que votre système soit en train de ralentir. à des niveaux inutilisables parce que la mémoire trop utilisée est expulsée de force pour échanger.

Je recommanderais de désactiver complètement le swap lors de cette tâche, afin que le tueur de mémoire insuffisante agisse dès que la mémoire RAM est pleine.

Solutions alternatives:

  • Augmentez la vitesse de lecture du swap en plaçant votre partition swap dans RAID1
    • Ou RAID0 si vous vous sentez risqué mais que cela entraînera un grand nombre de programmes en cours d'exécution si l'un de vos disques ne fonctionne pas correctement.
  • Diminuez le nombre de travaux de construction simultanés ("plus de cœurs = plus de vitesse", nous le disons tous, en oubliant qu'il faut une charge linéaire en RAM)
  • Cela pourrait aller dans les deux sens, mais essayez d’activer zswapdans le noyau. Cela comprime les pages avant leur envoi sur swap, ce qui peut fournir juste assez de marge de manœuvre pour accélérer votre machine. D'un autre côté, cela pourrait devenir un obstacle à la compression / décompression supplémentaire.
  • Désactivez les optimisations ou utilisez un compilateur différent. L'optimisation du code peut parfois prendre plusieurs gigaoctets de mémoire. Si LTO est activé, vous allez également utiliser beaucoup de RAM à l'étape de la liaison. Si tout échoue, vous pouvez essayer de compiler votre projet avec un compilateur plus léger (par exemple tcc), au détriment d'une légère performance d'exécution affectant le produit compilé. (Ceci est généralement acceptable si vous le faites à des fins de développement / débogage.)
Score_Under
la source
6
Si le swap est désactivé, c'est le comportement de Linux lorsque vous manquez de mémoire. Si Linux n'invoque pas le destructeur de mémoire insuffisante mais se bloque à la place, cela peut signifier qu'il existe des problèmes plus graves avec l'installation. Bien sûr, si swap est activé, le comportement est légèrement différent.
Score_Under
10
@ Akiva Avez-vous déjà essayé sans échange? Cette réponse est parfaite. J'aimerais ajouter que le fait de courir sudo swapoff -apeut vous faire économiser une fois que vous êtes déjà dans une impasse: cela arrêtera immédiatement toute utilisation supplémentaire d'espace de permutation, c'est-à-dire que le destructeur de MOO devrait être invoqué dans l'instant qui suit et mettre la machine en état de fonctionner. sudo swapoff -aest également une excellente mesure de précaution lors du débogage de fuites de mémoire ou lors de la compilation, par exemple, de Firefox. Normalement, le swap est un peu utile (par exemple pour l'hibernation ou le remplacement de données réellement inutiles), mais lorsque vous utilisez réellement la mémoire, les blocages sont encore pires.
Jonas Schäfer
2
@Score_Under: Des partitions d'échange séparées sur chaque disque sont censées être nettement plus efficaces que l'échange sur un périphérique md raid0. J'oublie où j'ai lu ça. Le wiki RAID Linux recommande des partitions séparées sur raid0, mais ne dit pas très bien pourquoi c'est meilleur . En tout cas, oui, RAID1 ou RAID10n2 est logique pour l’échange, en particulier si vous voulez simplement pouvoir échanger des pages sales mais très froides pour laisser plus de RAM pour la pagecache. c'est-à-dire que les performances d'échange ne sont pas un gros problème.
Peter Cordes
2
Ce que je veux dire, c'est que, selon vos conseils, il se peut que vous ne puissiez pas exécuter ces programmes, car ils doivent être échangés. Une version qui échoue 100% du temps est pire qu'une version qui a 50% de chances de verrouiller le système, n'est-ce pas?
Dmitry Grigoryev
2
Sans échange, sur de nombreuses machines, il est impossible de compiler de gros morceaux de code. Pourquoi supposeriez-vous que c'est la compilation qu'il veut sacrifier?
David Schwartz
14

Vous pouvez utiliser la commande suivante (plusieurs fois si nécessaire) pour tuer le processus en utilisant le plus de RAM possible sur votre système:

ps -eo pid --no-headers --sort=-%mem | head -1 | xargs kill -9

Avec:

  • ps -eo pid --no-headers --sort=-%mem: affiche les ID de processus de tous les processus en cours, triés par utilisation de la mémoire
  • head -1: ne conserve que la première ligne (processus utilisant le plus de mémoire)
  • xargs kill -9: tuer le processus

Editez après le commentaire précis de Dmitry:

Il s'agit d'une solution rapide et incorrecte à exécuter lorsque aucune tâche sensible n'est en cours d'exécution (tâches que vous ne souhaitez pas exécuter kill -9).

Gohu
la source
5
C’est bien pire que de laisser le tueur OOM gérer la situation. Le tueur OOM est beaucoup plus intelligent que cela. Exécutez-vous réellement de telles commandes sur un ordinateur avec des compilations en cours?
Dmitry Grigoryev
@DmitryGrigoryev c'est tellement intelligent de tuer parfois Xorg sur mon bureau. Dans les noyaux modernes, OOMK semble avoir acquis un peu de santé mentale, mais je ne lui ferais pas vraiment confiance après tout cela.
Ruslan
11

Avant d’exécuter vos commandes qui consomment des ressources, vous pouvez également utiliser l’ appel système setrlimit (2) , probablement avec l’ ulimitintégration de votre shell bash (ou limitde zsh), notamment avec -vfor RLIMIT_AS. Ensuite , trop grande consommation d'espace d'adressage virtuel (par exemple avec mmap (2) ou sbrk (2) utilisé par malloc (3) ) échouera (avec errno (3) étant ENOMEM).

Ensuite, ils (les processus affamés dans votre shell, après que vous ayez tapé ulimit) soient terminés avant de geler votre système.

Lisez également Linux Ate My RAM et envisagez de désactiver le surengagement de la mémoire (en exécutant la commande en echo 0 > /proc/sys/vm/overcommit_memory tant que root, voir proc (5) ...).

Basile Starynkevitch
la source
11

cela me arrive assez souvent lorsque je compile un logiciel en arrière-plan

Dans ce cas, quelque chose comme "killall -9 make" (ou ce que vous utilisez pour gérer votre compilation, sinon make). Cela arrêtera la procédure de compilation plus loin, SIGHUP tous les processus de compilateur lancés à partir de celui-ci (en les faisant s'arrêter également) et, en prime, pas besoin de sudo en supposant que vous compilez comme le même utilisateur que vous êtes connecté dans comme. Et comme il tue la cause réelle de votre problème au lieu de votre navigateur Web, de votre session X ou de certains processus au hasard, il n’interférera pas avec tout ce que vous faisiez sur le système à ce moment-là.

fluffysheap
la source
2
C'est juste dommage que j'ai dû défiler jusqu'à présent pour trouver cette réponse. J'espérais que quelqu'un proposerait un moyen de suspendre les progrès de ce mangeur de RAM.
TOOGAM
Il n’ya rien qui corresponde à la réponse attendue par OP, mais cela répond à la question littéraire: ma machine à merde est rendue inutilisable lorsque je bâtis dessus - arrêtez de construire sur une machine à merde.
9ilsdx 9rvj 0lo
9

Créez encore plus de swap pour vous-même.

Ce qui suit va ajouter 8G de swap:

dd if=/dev/zero of=/root/moreswap bs=1M count=8192
mkswap /root/moreswap
swapon /root/moreswap

Il sera toujours lent (vous échangez) mais vous ne devriez pas réellement vous épuiser. Les versions modernes de Linux peuvent échanger des fichiers. De nos jours, la seule utilisation d'une partition de swap est l'hibernation de votre ordinateur portable.

William Hay
la source
1
J'ai cette méthode implémentée sous forme de script, en fait, ici . Très utile pour ajouter swap à la volée.
Sergiy Kolodyazhnyy
7
Certains échanges sont généralement judicieux, mais allouer de grandes quantités permet simplement à la machine de se débattre davantage avant que le tueur OOM n’intervienne et choisisse un volontaire. Le vieux rôle du pouce sur le «double ton bélier en échange» est mort depuis longtemps. Personnellement, je ne vois aucune valeur à allouer plus d’environ 1 Go de swap total.
Criggie
5
Avec ext4, vous pouvez éviter, au fallocate -l 8G /root/moreswaplieu de cela, de ddfaire 8 Go d’entrées / sorties pendant que le système tourne. Cela ne fonctionne avec aucun autre système de fichiers, cependant. Certainement pas XFS, où swapon considère les étendues non écrites comme des trous. (Je suppose que cette discussion sur la liste de diffusion xfs n'a pas abouti ). Voir aussi swapd, un démon qui crée / supprime des fichiers d'échange à la volée pour économiser de l'espace disque. Aussi askubuntu.com/questions/905668/…
Peter Cordes
1
@Criggie "Personnellement, je ne vois aucune valeur à allouer plus de ~ 1 Go de swap au total" - Avez-vous essayé de construire Firefox?
Dmitry Grigoryev
1
@Akiva La dernière fois que j'ai vérifié, la configuration de construction recommandée était de 16 Go de RAM. Le fichier exécutable principal ( xul.dll) fait environ 50 Mo. Il est donc environ 10 fois plus lourd que le noyau Linux.
Dmitry Grigoryev
5

Un moyen d’obtenir rapidement un bloc de RAM libre consiste à utiliser zram , qui crée un disque RAM compressé et l’échange à cet endroit . Avec n'importe quel processeur à moitié décent, cela est beaucoup plus rapide qu'un échange standard et les taux de compression sont assez élevés avec de nombreux porcs RAM modernes comme les navigateurs Web.

En supposant que zram soit installé et configuré, tout ce que vous avez à faire est d’exécuter

sudo service zramswap start
Dmitry Grigoryev
la source
Est-ce que cela fonctionne sur tous les systèmes de fichiers comme btrfs?
Akiva
1
@ Akiva Zram ne touche jamais le disque, donc je dirais que oui;)
Dmitry Grigoryev
3

sudo swapoff -adésactivera l’échange, faisant que le noyau tue automatiquement le processus avec le score le plus élevé si le système manque de mémoire. J'utilise ceci si je sais que je vais exécuter quelque chose avec beaucoup de mémoire vive que je préférerais tuer si cela échappait à tout contrôle que de le laisser entrer en échange et rester bloqué pour toujours. Utilisez sudo swapon -apour le réactiver par la suite.

Plus tard, vous voudrez peut-être examiner vos paramètres de swap. On dirait que votre swap se trouve sur le même disque que la partition racine, ce qui ralentirait le système lorsque vous utiliserez le swap; évitez donc cela si vous le pouvez. De plus, à mon avis, les systèmes modernes sont souvent configurés avec trop d'échange. 32GiB RAM signifie généralement que l’échange 32GiB est alloué par défaut, comme si vous souhaitiez réellement mettre 32GiB dans votre espace de swap.

sudo
la source
Oh, je viens de voir que quelqu'un a commenté cela quelque part.
sudo le
3

Une autre chose à faire est de libérer du cache de page mémoire via cette commande:

echo 3 | sudo tee /proc/sys/vm/drop_caches

De la documentation de kernel.org (soulignement ajouté):

drop_caches

En écrivant ceci, le noyau lâchera des caches propres, ainsi que des objets de dalle récupérables comme les dentries et les inodes. Une fois largué, leur mémoire devient libre .

Pour libérer pagecache: echo 1> / proc / sys / vm / drop_caches Pour libérer les objets de dalle récupérables (y compris les dentiers et les inodes): echo 2> / proc / sys / vm / drop_caches Pour libérer les objets de dalle et la pagecache: echo 3> / proc / sys / vm / drop_caches

Ceci est une opération non destructive et ne libérera aucun objet sale. Pour augmenter le nombre d'objets libérés par cette opération, l'utilisateur peut exécuter «sync» avant d'écrire dans / proc / sys / vm / drop_caches. Cela minimisera le nombre d'objets souillés sur le système et créera plus de candidats à abandonner.

Sergiy Kolodyazhnyy
la source
Intéressant ... soin d'expliquer cette logique de commande?
Akiva
1
@ Akiva en gros, cela demande au noyau Linux de libérer de la RAM. Cela ne supprime pas la cause, qui tue le processus en cause, alors la réponse d'Oli est la solution au problème. La suppression de caches empêchera votre système de manquer de mémoire, évitant ainsi le gel des données, vous permettant ainsi de gagner du temps pour résoudre le problème. Ce sera probablement un peu plus rapide que de créer un fichier d'échange, surtout si vous êtes sur un disque dur et non sur SSD
Sergiy Kolodyazhnyy
7
La mémoire cache est la première chose à faire lorsque vous remplissez la mémoire. Je ne pense donc pas que cela vous aidera beaucoup. En fait, je ne pense pas que cette commande ait une utilisation pratique en dehors du débogage du comportement du noyau ou de l'optimisation des optimisations de l'accès au disque. Je recommanderais humblement de ne pas exécuter cette commande sur tout système ayant besoin de plus de performances.
Score_Under
2
@Score_Under - "Le cache est la première chose à faire lorsque vous remplissez la mémoire" - cela dépend de votre configuration /proc/sys/vm/swappiness. Avec swappiness réglé sur 0, vous avez raison. Avec le réglage par défaut de 60, vous êtes proche. Avec 200, cependant, ce seront les pages les moins utilisées des processus en cours qui ont été abandonnées en premier ... Dans ce cas particulier, cette commande peut être utile. Cependant, définir swappiness sur 0 (ou une valeur faible, peut-être 20 ou 30) constituerait une meilleure approche générale, cependant.
Jules
3
@Score_Under Cette commande était utile sur les anciens noyaux avec un kswapdbogue (certaines personnes ont même créé des tâches cron avec celui-ci). Mais vous avez raison, je doute que cela aide à résoudre cette question.
Dmitry Grigoryev
1

Vous avez dit "compiler en tâche de fond". Que fais-tu au premier plan? Si vous développez avec Eclipse ou un autre IDE très gourmand en ressources, vérifiez si tout se termine correctement dans la console.

Les environnements de développement permettent souvent de démarrer plusieurs processus en cours de développement, ceux-ci peuvent rester en suspens même une fois que vous n'êtes plus intéressé par eux (dans le débogueur ou tout simplement pas correctement finis). Si le développeur ne fait pas attention, des dizaines de processus oubliés peuvent s'accumuler au cours de la journée, en utilisant plusieurs gigaoctets ensemble.

Vérifiez si tout ce qui doit être terminé dans IDE est terminé.

h22
la source