Accueil

OOM killer : pourquoi votre processus meurt sans message d'erreur

Linux 5 min de lecture

Un service disparaît sans trace dans ses propres journaux. Comment le noyau choisit sa victime, pourquoi ce n'est presque jamais le vrai coupable, et les réglages qui protègent les bons processus.

L'essentiel

  • Un processus tué par le noyau pour manque de mémoire ne peut rien écrire : le signal reçu est non interceptable.
  • La preuve est dans les journaux du noyau, pas dans ceux de l'application — c'est le premier endroit à regarder.
  • Le noyau choisit sa victime par un score : le plus gourmand est visé, pas forcément le fautif.
  • Linux surengage la mémoire : il en promet plus qu'il n'en a, d'où une pénurie détectée seulement à l'usage réel.
  • La vraie protection passe par des limites mémoire par service, qui isolent le fautif au lieu de sacrifier un voisin.

Le service ne répond plus. Vous consultez ses journaux : rien. Pas d'erreur, pas d'avertissement, pas de message d'arrêt. La dernière ligne est une entrée parfaitement ordinaire, comme si le processus s'était volatilisé au milieu d'une phrase.

C'est exactement ce qui s'est passé.

Pourquoi l'application n'a rien pu écrire

Quand le noyau manque de mémoire au point de ne plus pouvoir satisfaire une allocation, il choisit un processus et le supprime.

Le signal employé est non interceptable. Le processus ne peut ni le capter, ni l'ignorer, ni exécuter la moindre routine de terminaison. Il ne ferme pas ses fichiers, ne vide pas ses tampons, n'écrit aucune ligne d'adieu. Il s'arrête, point.

D'où le symptôme caractéristique : des journaux applicatifs qui se terminent sur une ligne banale, sans la moindre trace de ce qui s'est produit.

La preuve est ailleurs — dans les journaux du noyau, où l'événement est systématiquement consigné avec le processus visé, son score, et un état de la mémoire au moment des faits. C'est le premier endroit à regarder quand un service disparaît sans explication.

La victime n'est presque jamais le coupable

Le noyau attribue à chaque candidat un score fondé principalement sur la mémoire consommée, puis élimine celui dont le score est le plus élevé.

La logique se défend : tuer le plus gros libère le plus de mémoire, donc résout la crise en une seule victime.

Mais elle produit un résultat trompeur. Le processus tué est le plus gros consommateur, pas celui qui a déclenché la pénurie.

Le scénario typique : un script mal écrit charge un fichier de plusieurs gigaoctets en mémoire d'un seul coup. La mémoire se sature. Le noyau regarde qui consomme le plus — et trouve la base de données, qui occupe légitimement une large part de la machine depuis des semaines. Elle est éliminée.

Vous cherchez alors ce qui cloche dans la base de données. Elle n'a rien fait de mal : elle était simplement la plus visible.

Réflexe de diagnostic : ne cherchez pas la cause dans le processus tué. Cherchez ce qui a brusquement réclamé de la mémoire juste avant — l'état mémoire consigné par le noyau au moment de l'incident donne souvent la réponse.

Le surengagement, ou pourquoi l'erreur arrive trop tard

Une question naturelle : pourquoi le système accepte-t-il des allocations qu'il ne peut pas honorer, au lieu de refuser proprement ?

Parce que Linux surengage délibérément la mémoire. Les programmes réservent presque toujours beaucoup plus qu'ils n'utiliseront, et refuser ces réservations gaspillerait massivement les ressources.

Le noyau promet donc au-delà de sa capacité, en pariant que tout le monde ne consommera pas simultanément. Ce pari est gagnant l'immense majorité du temps.

Le revers, c'est que la pénurie n'est constatée qu'au moment de l'usage réel — quand une page est effectivement écrite. À cet instant, il est trop tard pour renvoyer une erreur d'allocation au programme fautif : la seule issue est de tuer quelqu'un.

Ce comportement est réglable, mais le rendre strict a un coût élevé : de nombreux programmes considèrent le surengagement comme acquis et échouent à démarrer dans un mode strict. Ce n'est pas un réglage à modifier sans mesurer.

Le swap : du temps, pas de la mémoire

Ajouter du swap est le conseil réflexe. Il est partiellement pertinent.

Le swap offre une marge : les pages rarement utilisées migrent sur disque, ce qui permet d'absorber un pic ponctuel sans arrêt brutal. Sur une machine correctement dimensionnée, il évite des incidents inutiles.

Mais si la charge dépasse durablement la mémoire physique, le système passe son temps à déplacer des pages entre disque et mémoire. Les performances s'effondrent — la machine devient parfois moins réactive qu'un arrêt franc — et le processus finit tué malgré tout, après une longue agonie.

Le swap achète du temps. Il ne crée pas de mémoire.

La bonne protection : les limites par service

Il est possible d'ajuster le score d'un processus pour le rendre moins susceptible d'être choisi. C'est un correctif grossier : vous ne supprimez pas le problème, vous désignez simplement quelqu'un d'autre.

L'approche saine consiste à imposer une limite mémoire par service, via les groupes de contrôle. Le gestionnaire de services de la plupart des distributions permet de la déclarer directement dans la définition du service.

Le changement est fondamental : un service qui dépasse sa limite déclenche un traitement à l'intérieur de son propre groupe. Le fautif est éliminé, les autres services ne sont jamais inquiétés.

Vous passez d'un modèle où la pénurie frappe au hasard le plus gros, à un modèle où chaque service assume ses propres excès. Sur une machine hébergeant plusieurs services, c'est la seule approche qui rende les incidents prévisibles.

La marche à suivre

  1. Confirmez la cause dans les journaux du noyau : sans cette confirmation, vous cherchez peut-être un bug qui n'existe pas.
  2. Identifiez ce qui a brusquement réclamé de la mémoire, pas ce qui a été tué.
  3. Posez des limites par service pour que le prochain incident touche le fautif.
  4. Alertez sur la mémoire disponible, pas seulement sur la mémoire utilisée — le cache fausse la lecture de la seconde.

Et si l'incident se répète malgré des limites correctes, la conclusion est simple : la machine est sous-dimensionnée pour ce qu'on lui demande. Aucun réglage ne compense durablement un manque réel de mémoire.

Questions fréquentes

Comment savoir si mon processus a été tué par manque de mémoire ?
Regardez les journaux du noyau, pas ceux de l'application. Le noyau y consigne systématiquement l'événement, avec le nom du processus visé, son score, et un état de la mémoire au moment des faits. L'application, elle, n'a rien pu écrire : le signal utilisé est non interceptable, le processus s'arrête immédiatement sans exécuter la moindre routine de fin. C'est pourquoi ses journaux se terminent sur une ligne parfaitement banale.
Comment le noyau choisit-il quel processus tuer ?
Il calcule un score pour chaque candidat, principalement fondé sur la quantité de mémoire consommée, ajusté par un facteur configurable. Le processus au score le plus élevé est éliminé. La conséquence est déroutante : la victime est le plus gros consommateur, pas nécessairement celui qui a provoqué la pénurie. Une base de données qui occupe légitimement beaucoup de mémoire sera tuée avant le script mal écrit qui vient d'en réclamer trois gigaoctets d'un coup.
Pourquoi Linux accepte-t-il d'allouer plus de mémoire qu'il n'en a ?
C'est le surengagement, et c'est délibéré. Les programmes réservent presque toujours plus de mémoire qu'ils n'en utilisent réellement ; refuser ces réservations gaspillerait massivement les ressources. Le noyau promet donc au-delà de sa capacité, en pariant que tout le monde ne consommera pas en même temps. Le revers est que la pénurie n'est détectée qu'au moment de l'usage réel — trop tard pour renvoyer proprement une erreur d'allocation à qui de droit.
Ajouter du swap règle-t-il le problème ?
Cela le décale plutôt qu'il ne le résout. Le swap donne au système une marge pour absorber les pics et évite des arrêts brutaux lors de dépassements ponctuels — c'est utile. Mais si la charge dépasse durablement la mémoire physique, le système passe son temps à échanger des pages, les performances s'effondrent, et le processus finit tué de toute façon, après une longue période d'agonie. Le swap achète du temps, il ne crée pas de mémoire.
Comment protéger un service critique ?
Deux leviers complémentaires. Le premier est le facteur d'ajustement du score, qui rend un processus plus ou moins susceptible d'être choisi. C'est un correctif grossier : il déplace le problème sur un voisin. Le second, bien meilleur, consiste à imposer une limite mémoire par service via les groupes de contrôle. Le service qui dépasse sa limite est traité à l'intérieur de son groupe : le fautif est isolé et les autres ne sont jamais inquiétés.

Cet article vous a plu ?

Cet article vous a-t-il été utile ?

Merci pour votre retour !

Commentaires

MR
Morgann Riu

Expert en cybersécurité et administration Linux. J'aide les entreprises à sécuriser et optimiser leurs infrastructures critiques.

Linux OOM mémoire diagnostic cgroups administration dépannage

Recommandé pour vous

Tuto associé

Retour au blog