Le oom-killer a généralement une mauvaise réputation auprès des utilisateurs de Linux. Cela peut être en partie la raison pour laquelle Linux ne l'invoque que lorsqu'il n'a absolument pas d'autre choix. Il remplacera l'environnement de bureau, supprimera tout le cache de la page et videra chaque tampon avant de finalement tuer un processus. C'est du moins ce que je pense que cela fera. Je n'ai pas encore été assez patient pour l'attendre, assis devant un système qui ne répond pas.
Cela m'a amené, ainsi que d'autres personnes, à me demander si le oom-killer pouvait être configuré pour intervenir plus tôt : reddit r/linux, superuser.com, unix.stackexchange.com.
Il s’avère que non, ce n’est pas possible. Au moins en utilisant le oom-killer intégré au noyau. Dans l’espace utilisateur, cependant, nous pouvons faire ce que nous voulons.
earlyoom se veut simple et solide. Il est écrit en C pur sans dépendances. Une suite de tests complète (tests unitaires et d'intégration) est écrite en Go.
earlyoom vérifie la quantité de mémoire disponible et l'échange gratuit jusqu'à 10 fois par seconde (moins souvent s'il y a beaucoup de mémoire libre). Par défaut, si les deux sont inférieurs à 10 %, cela tuera le processus le plus important ( oom_score
le plus élevé). La valeur en pourcentage est configurable via des arguments de ligne de commande.
Dans la sortie free -m
ci-dessous, la mémoire disponible est de 2 170 Mio et l'échange gratuit est de 231 Mio.
total used free shared buff/cache available Mem: 7842 4523 137 841 3182 2170 Swap: 1023 792 231
Pourquoi la mémoire « disponible » est-elle vérifiée par opposition à la mémoire « libre » ? Sur un système Linux sain, la mémoire « libre » est censée être proche de zéro, car Linux utilise toute la mémoire physique disponible pour mettre en cache l'accès au disque. Ces caches peuvent être supprimés chaque fois que la mémoire est nécessaire pour autre chose.
La mémoire "disponible" en tient compte. Il résume toute la mémoire inutilisée ou pouvant être libérée immédiatement.
Notez que vous avez besoin d'une version récente du noyau Linux free
et 3.14+ pour voir la colonne "disponible". Si vous disposez d'un noyau récent, mais d'une ancienne version de free
, vous pouvez obtenir la valeur depuis grep MemAvailable /proc/meminfo
.
Lorsque votre mémoire disponible et votre échange libre tombent en dessous de 10 % de la mémoire totale disponible pour les processus de l'espace utilisateur (= total partagé), il enverra le signal SIGTERM
au processus qui utilise le plus de mémoire de l'avis du noyau ( /proc/*/oom_score
).
nohang, un projet similaire à earlyoom, écrit en Python et avec des fonctionnalités et options de configuration supplémentaires.
les correctifs du noyau d'information sur le décrochage de pression (psi) de Facebook et l'assistant d'espace utilisateur oomd qui l'accompagne. Les correctifs sont fusionnés dans Linux 4.20.
earlyoom n'utilise pas echo f > /proc/sysrq-trigger
:
Dans certaines versions du noyau (testées sur la v4.0.5), le déclenchement manuel du kernel oom killer ne fonctionne pas du tout. Autrement dit, il ne peut libérer qu'une partie de la mémoire graphique (qui sera à nouveau allouée immédiatement) et ne tuer aucun processus. Ici vous pouvez voir à quoi cela ressemble sur ma machine (graphiques intégrés Intel).
Ce problème a été corrigé dans Linux v5.17 (commit f530243a).
Comme le ferait le noyau Linux, earlyoom trouve sa victime en lisant /proc/*/oom_score
.
Environ 2 MiB
( VmRSS
), bien que seulement 220 kiB
soient de la mémoire privée ( RssAnon
). Le reste est la bibliothèque libc ( RssFile
) partagée avec d'autres processus. Toute la mémoire est verrouillée à l'aide mlockall()
pour garantir que earlyoom ne ralentisse pas dans les situations de mémoire insuffisante.
Se compiler est simple :
git clone https://github.com/rfjakob/earlyoom.gitcd earlyoom faire
Facultatif : Exécutez les autotests intégrés :
faire un test
Démarrez earlyoom automatiquement en l'enregistrant en tant que service :
sudo make install # systemdsudo make install-initscript # non-systemd
Notez que pour les systèmes avec SELinux désactivé (Ubuntu 19.04, Debian 9 ...), les avertissements chcon signalant l'échec de la définition du contexte peuvent être ignorés en toute sécurité.
Pour Debian 10+ et Ubuntu 18.04+, il existe un package Debian :
sudo apt installer earlyoom
Pour Fedora et RHEL 8 avec EPEL, il existe un package Fedora :
sudo dnf installer earlyoom sudo systemctl activer --now earlyoom
Pour Arch Linux, il existe un package Arch Linux :
sudo pacman -S earlyoom sudo systemctl activer --now earlyoom
Disponibilité dans d'autres distributions : voir page repologie.
Lancez simplement l'exécutable que vous venez de compiler :
./tôt la nuit
Il vous informera de la quantité de mémoire et d'échange dont vous disposez, du minimum, de la quantité de mémoire disponible et de la quantité d'échange libre.
./earlyoom eearlyoom v1.8 mem total: 23890 MiB, user mem total: 21701 MiB, swap total: 8191 MiB sending SIGTERM when mem avail <= 10.00% and swap free <= 10.00%, SIGKILL when mem avail <= 5.00% and swap free <= 5.00% mem avail: 20012 of 21701 MiB (92.22%), swap free: 5251 of 8191 MiB (64.11%) mem avail: 20031 of 21721 MiB (92.22%), swap free: 5251 of 8191 MiB (64.11%) mem avail: 20033 of 21723 MiB (92.22%), swap free: 5251 of 8191 MiB (64.11%) [...]
Si les valeurs descendent en dessous du minimum, les processus sont tués jusqu'à ce qu'elles reviennent au-dessus du minimum. Chaque action est enregistrée dans stderr. Si vous exécutez earlyoom en tant que service systemd, vous pouvez afficher les 10 dernières lignes en utilisant
statut systemctl earlyoom
Afin de voir earlyoom
en action, créez/simulez une fuite de mémoire et laissez earlyoom
faire ce qu'il fait :
tail /dev/zero
Si vous avez besoin d'actions supplémentaires après la suppression d'un processus par earlyoom
(comme l'envoi d'e-mails), vous pouvez analyser les journaux comme suit :
sudo journalctl -u earlyoom | grep sending
Un exemple de sortie pour la commande de test ci-dessus ( tail /dev/zero
) ressemblera à :
Feb 20 10:59:34 debian earlyoom[10231]: sending SIGTERM to process 7378 uid 1000 "tail": oom_score 156, VmRSS 4962 MiB
Pour les anciennes versions de
earlyoom
, utilisez :sudo journalctl -u earlyoom | grep -iE "(sending|killing)"
Depuis la version 1.6, earlyoom peut envoyer des notifications sur les processus tués via le système d-bus. Passez -n
pour les activer.
Pour voir réellement les notifications dans votre session GUI, vous devez avoir systembus-notify exécuté en tant qu'utilisateur.
De plus, earlyoom peut exécuter un script pour chaque processus tué, fournissant des informations sur le processus via les variables d'environnement EARLYOOM_PID
, EARLYOOM_UID
et EARLYOOM_NAME
. Passez -N /path/to/script
pour l'activer.
Avertissement : en cas de mode dryrun, le script sera exécuté en succession rapide, assurez-vous d'avoir implémenté une sorte de limite de débit.
L'indicateur de ligne de commande --prefer
spécifie les processus qui préfèrent tuer ; de même, --avoid
spécifie les processus pour éviter de tuer. Voir https://github.com/rfjakob/earlyoom/blob/master/MANPAGE.md#--prefer-regex pour plus de détails.
Si vous exécutez earlyoom en tant que service système (via systemd ou init.d), vous pouvez ajuster sa configuration via le fichier fourni dans /etc/default/earlyoom
. Le fichier contient déjà quelques exemples dans les commentaires, que vous pouvez utiliser pour créer votre propre ensemble de configuration basé sur les options de ligne de commande prises en charge, par exemple :
EARLYOOM_ARGS="-m 5 -r 60 --avoid '(^|/)(init|Xorg|ssh)$' --prefer '(^|/)(java|chromium)$'"
Après avoir ajusté le fichier, redémarrez simplement le service pour appliquer les modifications. Par exemple, pour systemd :
systemctl redémarre earlyoom
Veuillez noter que ce fichier de configuration n'a aucun effet sur les instances earlyoom en dehors de systemd/init.d.
earlyoom v1.8 Usage: ./earlyoom [OPTION]... -m PERCENT[,KILL_PERCENT] set available memory minimum to PERCENT of total (default 10 %). earlyoom sends SIGTERM once below PERCENT, then SIGKILL once below KILL_PERCENT (default PERCENT/2). -s PERCENT[,KILL_PERCENT] set free swap minimum to PERCENT of total (default 10 %). Note: both memory and swap must be below minimum for earlyoom to act. -M SIZE[,KILL_SIZE] set available memory minimum to SIZE KiB -S SIZE[,KILL_SIZE] set free swap minimum to SIZE KiB -n enable d-bus notifications -N /PATH/TO/SCRIPT call script after oom kill -g kill all processes within a process group -d, --debug enable debugging messages -v print version information and exit -r INTERVAL memory report interval in seconds (default 1), set to 0 to disable completely -p set niceness of earlyoom to -20 and oom_score_adj to -100 --ignore-root-user do not kill processes owned by root --sort-by-rss find process with the largest rss (default oom_score) --prefer REGEX prefer to kill processes matching REGEX --avoid REGEX avoid killing processes matching REGEX --ignore REGEX ignore processes matching REGEX --dryrun dry run (do not kill any processes) --syslog use syslog instead of std streams -h, --help this help text
Consultez la page de manuel pour plus de détails.
Les rapports de bogues et les demandes d'extraction sont les bienvenus via github. En particulier, je suis heureux d'accepter
Rapports de cas d'utilisation et commentaires
Nous n'utilisons pas procps/libproc2 car procps_pids_select(), pour une raison quelconque, analyse toujours /proc/$pid/status. C'est relativement cher et nous n'en avons pas besoin.
v1.8.2, 2024-05-07
Ajouter process_mrelease
aux appels système autorisés (commit)
Correction de la syntaxe IPAddressDeny
(commit)
Autoriser -p
(valider)
Correctifs dans le fichier d'unité systemd earlyoom.service
v1.8.1, 2024-04-17
Correction d'échecs de tests triviaux causés par la reformulation du message (commit)
v1.8, 2024-04-15
Présentez user mem total
/ meminfo_t.UserMemTotal
et calculez MemAvailablePercent en fonction de cela (commit, plus d'informations dans la page de manuel)
Utilisez process_mrelease
(#266)
Soutenez NO_COLOR
(https://no-color.org/)
Ne vous laissez pas tromper par les processus avec un thread principal zombie (commit)
Ajoutez --sort-by-rss
, merci @RanHuang ! Cela sélectionnera un processus pour tuer acc. au plus grand RSS au lieu du plus grand oom_score.
La suite de tests Gitlab CI fonctionne désormais également sur Amazon Linux 2 et Oracle Linux 7.
v1.7, 2022-03-05
Ajoutez l'indicateur -N
pour exécuter un script à chaque fois qu'un processus est tué (commit, section de la page de manuel)
Ajoutez l'indicateur -g
pour tuer tout le groupe de processus (#247)
Supprimez l'indicateur -i
(ignoré pour des raisons de compatibilité), il ne fonctionne pas correctement sur les noyaux Linux 5.9+ (#234)
Renforcement : suppression des capacités ambiantes au démarrage (#234)
v1.6.2, 2020-10-14
Revérifier la situation de la mémoire avant de tuer la victime (valider)
Ne jamais nous terminer (#205)
Tampon de vidage lors de l'erreur de conversion /proc/meminfo (#214)
1.6.1, 2020-07-07
Nettoyer les processus zombies dbus-send (#200)
Ignorer les processus avec oom_score_adj=-1000 (210)
1.6, 2020-04-11
-n
/ -N
active désormais la nouvelle logique
Vous devez avoir systembus-notify exécuté dans votre session GUI pour les notifications de travail
Remplacez l'ancienne logique de notification de l'interface graphique notify-send
par dbus-send
/ systembus-notify (#183)
Gérer /proc
monté avec hidepid avec élégance (numéro 184)
v1.5, 2020-03-22
-p
: définit oom_score_adj à -100
au lieu de -1000
(#170)
Autoriser l'utilisation à la fois -M
et -m
, ainsi que -S
et -s
. La valeur la plus basse (convertie en pourcentages) sera utilisée.
Définissez l'intervalle de rapport de mémoire dans earlyoom.default
sur 1 heure au lieu de 1 minute (#177)
v1.4, 2020-03-01
Utilisez des variables locales de bloc lorsque cela est possible
Introduisez PATH_LEN pour remplacer plusieurs longueurs de tampon codées en dur
Rendre la logique de sélection des victimes 50 % plus rapide grâce au chargement paresseux des attributs du processus
Enregistrez l' uid
utilisateur des processus tués en plus du pid et du nom.
Journal de débogage couleur en gris clair
Nettoyage du code
Développer la suite de tests ( make test
)
Exécutez cppcheck
lorsqu'il est disponible
Ajouter des benchmarks de tests unitaires ( make bench
)
Supprimez les privilèges root dans le fichier d'unité systemd earlyoom.service
v1.3.1, 2020-02-27
Correction d'un faux échec de suite de tests sur les systèmes avec beaucoup de RAM (problème n° 156)
v1.3, 2019-05-26
Ne quittez pas avec une erreur fatale si la limite SIGTERM < limite SIGKILL
Autoriser la limite SIGKILL nulle
Cela résout le problème selon lequel earlyoom tue parfois plus d'un processus alors qu'un seul suffirait (problème n°121)
Attendez que les processus se terminent réellement lors de l'envoi d'un signal
Soyez plus libéral dans les limites acceptées pour SIGTERM et SIGKILL (numéro 97)
Reformatez la sortie de démarrage pour indiquer clairement que les DEUX swap et mem doivent être <= limite
Ajouter un script d'assistance notify_all_users.py
Ajouter CODE_OF_CONDUCT.md (Contributor Covenant 1.4) (#102)
Correction des noms d'applications UTF8 éventuellement tronqués dans la sortie du journal (#110)
v1.2, 2018-10-28
Implémenter un temps de veille adaptatif (= taux d'interrogation adaptatif) pour réduire davantage l'utilisation du processeur (problème n° 61)
Supprimer l'option permettant d'utiliser le noyau oom-killer ( -k
, désormais ignoré pour des raisons de compatibilité) (numéro 80)
Gérer gracieusement le cas où un swap est ajouté ou supprimé après le démarrage d'Earlyoom (numéro 62, commit)
Implémenter le kill par étapes : d'abord SIGTERM, puis SIGKILL, avec des limites configurables (numéro 67)
v1.1, 2018-07-07
Correction d'une éventuelle injection de code shell via les notifications de l'interface graphique (commit)
En cas d'échec de l'arrêt d'un processus, ne dormez que 1 seconde au lieu de 10 (problème n°74)
Envoyer la notification GUI après le meurtre, pas avant (problème n°73)
Acceptez --help
en plus de -h
Correction d'un nom de processus incorrect dans le journal et dans la notification d'arrêt (commit 1, commit 2, problème n° 52, problème n° 65, problème n° 194)
Correction d'une éventuelle division par zéro avec -S
(commit)
v1.0, 2018-01-28
Ajoutez les options --prefer
et --avoid
(@TomJohnZ)
Ajoutez la prise en charge des notifications GUI, ajoutez les options -n
et -N
v0.12 : Ajouter les options -M
et -S
(@nailgun) ; ajouter une page de manuel, paramétrer Makefile (@yangfl)
v0.11 : Correction d'un comportement non défini dans get_entry_fatal (retour manquant, commit)
v0.10 : Autoriser le remplacement de la variable VERSION de Makefile pour faciliter l'empaquetage, ajouter l'option de ligne de commande -v
v0.9 : Si oom_score de tous les processus est 0, utilisez VmRss pour trouver une victime
v0.8 : utilisez une estimation si le noyau ne fournit pas MemAvailable
v0.7 : Sélectionnez la victime par oom_score au lieu de VmRSS, ajoutez les options -i
et -d
v0.6 : Ajouter des options de ligne de commande -m
, -s
, -k
v0.5 : ajout de la prise en charge des échanges
v0.4 : ajoutez un script d'initialisation SysV (merci @joeytwiddle), utilisez le nouveau MemAvailable
depuis /proc/meminfo
(nécessite Linux 3.14+, commit)
v0.2 : Ajouter un fichier d'unité systemd
v0.1 : version initiale