Tom Daluzeau
← Parcours Linux · ressources
Linux · ressources · leçon 2 / 6Ch. 2 · Ressources10 minTerminée

Mémoire : free, cache, swap et OOM killer

Tu sais lire free -h sans te faire piéger par la colonne free, expliquer pourquoi le cache disque n'est pas de la mémoire perdue, régler vm.swappiness, et retrouver dans les journaux du noyau quel processus l'OOM killer a tué.

Mis à jour le

À recouper avec le cours. Cette leçon a été écrite à partir du plan du chapitre, avant relecture avec les supports. En cas de doute, le cours fait foi.

Pourquoi on voit ça

Après le processeur, la deuxième ressource à vérifier quand un serveur rame, c’est la mémoire. Elle est piégeuse pour deux raisons.

D’abord, la commande free affiche presque toujours très peu de mémoire « libre », même sur un serveur en pleine forme. Beaucoup de débutants paniquent pour rien. Ensuite, quand la mémoire manque vraiment, Linux ne prévient pas : il tue un processus. Un service disparaît en pleine nuit, sans une ligne dans ses journaux. Il faut savoir où chercher l’explication.

Lire free -h

free -h

-h comme human : les tailles sont affichées en Mio et Gio plutôt qu’en kibioctets.

               total        used        free      shared  buff/cache   available
Mem:           7.8Gi       2.1Gi       310Mi        12Mi       5.4Gi       5.7Gi
Swap:          2.0Gi          0B       2.0Gi

La ligne Mem décrit la RAM, la ligne Swap le swap (on y vient).

Colonne Ce qu’elle mesure
total la RAM installée
used la mémoire occupée par les programmes et le noyau
free la mémoire qui ne sert à rien du tout en ce moment
buff/cache la mémoire utilisée comme cache disque
available la mémoire qu’une application peut encore obtenir

La colonne qui compte, c’est available. Elle additionne la mémoire libre et la partie du cache que le noyau peut rendre immédiatement.

Dans l’exemple, free vaut 310 Mio et available 5,7 Gio. Le serveur va très bien.

total 7,8 Gi free 310 Mi buff/cache 5,4 Gi : copies du disque used 2,1 Gi available 5,7 Gi : ce qu'une application peut encore obtenir
La colonne free ne compte que la toute petite case vide. available compte aussi le cache, que le noyau rend à la demande.

Le cache disque n’est pas de la mémoire perdue

Lire un fichier sur le disque est des milliers de fois plus lent que le lire en RAM. Le noyau a donc une règle simple : de la RAM inoccupée, c’est de la RAM gaspillée. Tout ce qu’il lit sur le disque, il en garde une copie en mémoire. Si le même fichier est redemandé, la réponse est immédiate.

C’est le cache disque, la colonne buff/cache.

Pense à ton bureau. Tu y laisses les dossiers que tu consultes souvent, au lieu de retourner à l’armoire à chaque fois. Le bureau a l’air encombré, mais si tu as besoin de place pour un nouveau travail, tu ranges un dossier en deux secondes. La place n’était pas perdue, elle était prêtée.

Le noyau fait pareil : dès qu’une application demande de la mémoire, il vide une partie du cache et la lui donne. Voilà pourquoi :

  • un free petit est normal sur un serveur allumé depuis longtemps ;
  • un buff/cache gros est une bonne nouvelle ;
  • le vrai signal d’alarme, c’est un available qui s’approche de zéro.

Le swap

Le swap est un espace sur le disque (une partition ou un fichier) qui sert de débordement à la RAM. Quand la mémoire se remplit, le noyau y déplace les pages mémoire les moins utilisées pour faire de la place.

L’avantage : le système ne s’écroule pas dès que la RAM est pleine. L’inconvénient : le disque est beaucoup plus lent que la RAM. Un programme dont la mémoire est partie en swap devient très lent dès qu’il en a de nouveau besoin.

Comment lire la ligne Swap de free :

Ce que tu vois Lecture
used à 0 la RAM a toujours suffi
un peu de swap utilisé, available confortable sans gravité : de vieilles pages inutilisées ont été mises de côté
swap presque plein et available très bas la machine manque de mémoire

vm.swappiness

Le paramètre vm.swappiness règle l’envie du noyau d’utiliser le swap. C’est un paramètre du noyau, il se lit et se modifie donc avec sysctl :

sysctl vm.swappiness
vm.swappiness = 60
  • Valeur haute : le noyau swappe volontiers, tôt, pour garder beaucoup de cache.
  • Valeur basse : le noyau évite le swap tant qu’il le peut.
  • 60 est la valeur par défaut sur Debian.

Sur un serveur de base de données, on préfère souvent une valeur basse, pour que les données restent en RAM :

sysctl -w vm.swappiness=10

Comme tout réglage fait avec sysctl -w, celui-ci disparaît au redémarrage. Pour le garder, tu écris la ligne vm.swappiness=10 dans /etc/sysctl.conf, puis tu l’appliques avec sysctl -p.

L’OOM killer

Que se passe-t-il quand la RAM et le swap sont pleins ? Le noyau ne peut plus donner de mémoire à personne. Plutôt que de laisser tout le système se figer, il déclenche l’OOM killer (Out Of Memory killer).

Ce qu’il fait :

  1. il donne un score à chaque processus, qui dépend surtout de la mémoire occupée ;
  2. il choisit celui qui a le score le plus élevé, donc en général le plus gros consommateur ;
  3. il le tue immédiatement, sans lui laisser le temps de s’arrêter proprement.

C’est un fusible : on sacrifie un processus pour sauver la machine. Le souci, c’est que le plus gros consommateur est souvent l’application principale du serveur (la base de données, le serveur Java…).

1. La RAM se remplit 2. Le swap prend le relais 3. Tout est plein RAM swap (disque) RAM swap (disque) RAM swap (disque) on vide d'abord le cache pages peu utilisées copiées sur le disque, lent l'OOM killer tue le processus au plus gros score
Le swap évite le crash mais il est lent. Quand lui aussi est plein, le noyau sacrifie un processus.

Retrouver sa trace

Le processus tué n’a pas eu le temps d’écrire quoi que ce soit. La trace est dans les messages du noyau. Deux façons de les lire :

dmesg | grep -i "out of memory"
journalctl -k | grep -i "out of memory"
nov. 13 03:12:44 srv1 kernel: Out of memory: Killed process 2143 (java) total-vm:9214580kB, anon-rss:7402112kB

La ligne donne le PID et le nom du processus tué, ainsi que la mémoire qu’il occupait.

nov. 13 03:12:44 srv1 kernel: Out of memory: Killed process quand machine le noyau écrit ce qui s'est passé 2143 (java) total-vm:9214580kB, anon-rss:7402112kB PID tué son nom la mémoire qu'il occupait la victime : PID et nom
La ligne vient du noyau, pas de l'application : c'est pour ça qu'elle n'apparaît que dans dmesg ou journalctl -k.
  • dmesg affiche les messages du noyau depuis le dernier démarrage. Sur Debian, il faut être root.
  • journalctl -k (-k comme kernel) affiche les mêmes messages, rangés dans le journal de systemd. Si le serveur a redémarré depuis, journalctl -k -b -1 montre ceux du démarrage précédent.

Le réflexe à garder : un service qui disparaît sans erreur dans ses propres journaux, c’est d’abord un soupçon d’OOM killer.

À retenir

  • Dans free -h, la colonne qui compte est available : ce qu’une application peut encore obtenir.
  • free petit et buff/cache gros, c’est normal : le noyau prête la RAM inoccupée au cache disque et la reprend à la demande.
  • Le swap est un débordement de la RAM sur le disque : il évite le crash, mais il est lent.
  • vm.swappiness (60 par défaut) : plus c’est bas, plus le noyau évite le swap. Durable dans /etc/sysctl.conf.
  • RAM et swap pleins : l’OOM killer tue le processus au plus mauvais score, souvent le plus gros.
  • Sa trace : dmesg ou journalctl -k, ligne « Out of memory: Killed process… ».

Entraînement

12 questions, dont 4 à compléter. Tu réponds, on passe à la suivante. La note arrive à la fin.

Cartes · 7

Réviser les cartes ici

Espace : retourner