• # La honte du noyau

    Posté par . En réponse au message Raisons susceptibles du déclenchement d'OOM killer. Évalué à 8.

    OOM killer (Out-Of-Memory Killer) est une fonctionnalite du kernel qui se declenche quand il n'y a plus aucune memoire disponible sur le systeme. Les operations d'allocation memoire ont sature la memoire physique, puis le swap, puis il ne reste plus de place pour allouer encore. A ce moment-la, le kernel prend son courage a deux mains et decide qu'il doit y avoir une application qui est decidement trop gourmande en memoire et qu'elle a ete donc forcement mal programmee et ne merite plus de vivre. Il observe les processes qui sont les plus gourmands en consommation memoire et les tue jusqu'a ce que le systeme recouvre assez de ressources pour continuer a fonctionner.

    Dans ton cas, tu as sans doute une application qui est partie en vrille en allouant de nouveaux objets en pagaille sans les liberer. Avec les infos que tu donnes je pencherais pour un probleme Java (JBoss). En aucun cas un filesystem ne peut declencher directement l'intrepide OOM killer. Si tu as de la chance, OOM killer decidera de tuer precisement l'application qui pose des problemes, mais rien n'empeche OOM killer de dezinguer ton serveur X ou bien ta session eclipse dans laquelle tu travailles depuis 2 jours sans sauvegardes. C'est lui qui choisit, pas toi.

    Dans le detail: OOM killer fait d'une machine Linux une veritable bombe a retardement pour toutes les applis qui ont besoin du maximum de memoire qu'elles peuvent allouer. Pour les applis desktop c'est encore acceptable mais pour du deploye industriellement c'est critiquement grave.

    Linux est (a priori) le seul Unix qui vienne avec cet infame OOM killer. La raison profonde derriere ce patch est le fait que le kernel Linux s'amuse a promettre bien plus de memoire qu'il ne peut en offrir (memory overcommitment). Application: ecrire une boucle qui alloue des paquets de 1 Meg a la fois et regarder combien on peut en allouer (mon noyau me promet jusqu'a 4 Gb sur une machine qui possede 512 Mb de RAM + 512 Mb de swap). Deuxieme essai: allouer les blocs en boucle jusqu'a ce que malloc retourne NULL, puis remplir de zero les zones allouees une par une. La RAM se remplit, puis le swap, puis apres c'est le bonheur: soit le noyau plante, soit OOM killer intervient et (parfois) tue d'autres processes vitaux du systeme, ce qui finit en desastre complet.

    Pourquoi le noyau s'amuse-t-il donc a promettre plus de memoire que ce dont il dispose? Apparemment c'est du a l'implementation de fork() qui commence par repliquer le process qui fait cet appel, incluant une copie complete de sa memoire, ce qui prend du temps. Generalement un process qui fork() fait immediatement un exec derriere, ce qui rend inutile la perte de temps de recopie de memoire. Le noyau prefere promettre a fork() de la memoire dont il ne se servira de toutes facons pas.

    Si ce comportement vous inquiete vous pouvez desactiver le memory overcommitment en manipulant des flags dans /proc/sys/vm (suivant la version de kernel). Attention alors: le systeme ralentit considerablement.