Bonjour,
Je ne suis pas expert Linux et Red Hat.
J'aurais cependant une question suite à un problème qui m'a été remonté.
OOM killer se déclenche sur un serveur d'application RHEL 4.0 32 bits sur lequel est également installé JBoss 4.0.3 SP1.
Est ce que le déclenchement d'OOM killer peut être expliqué par l'utilisation du filesystem OCSF2? (En effet, les données aplicatives sont écrites dans un SGBD Oracle)Ou est ce que cette explication est erronée?
Quels peuvent etre les autres raisons expliquant le déclenchement d'OOM killer (mauvaise gestion mémoire dans les programmes développés coté serveur d'application)?
Merci d'avance de vos lumières
# La honte du noyau
Posté par malin . Évalué à 8.
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.
[^] # Re: La honte du noyau
Posté par trng . Évalué à 1.
[^] # Fuite mémoire JBoss
Posté par Cyriaque . Évalué à 3.
Il s'agit très probablement bel et bien du serveur d'appli qui est fautif.
Une de vos applis sous JBoss provoque des fuites mémoires.
D'ailleurs si vous monitorez la mémoire prise par JBoss (par un simple top par exemple), vous verrez certainement la mémoire prise par celui allant en augmentant au fil du temps et de l'utilisation de l'appli fautive.
Et effectivement, une fois la RAM pleine, le Swap sera attaqué à son tour par JBoss sans jamais diminuer jusqu'à atteindre sa limite.
A ce moment, le kernel ne se posera plus de questions pour préserver la survie du système et fera le ménage en killant ce qui monopolise la mémoire.
Donc c'est bien au niveau des applis java sous JBoss qu'il faut investiguer.
Maintenant il ne s'agit pas nécessairement d'un problème d'objets mal gérés dont le Garbage Collector n'arriverait pas à se débarrasser. Car dans ce cas, théoriquement, vous finiriez par avoir des OutOfMemory Exceptions, et jamais ça ne dépasserait le cadre de la mémoire allouée à la JVM. Tout ce que vous auriez dans ces cas la, c'est un comportement instable de vos applis.
Le problème est donc plus "profond" et plus vicieux, car de la mémoire hors JVM est allouée et n'est jamais libérée.
Ca n'est pas particulièrement facile à diagnostiquer (bon courage d'ailleurs) mais ça peut être lié au système tout de même notamment dans la façon dont Java va interagir avec.
En gros, voyez si vos problèmes ne sont pas liés avec les points suivants (en vrac):
- mauvaise gestion de stream (ex: un InputStream ou OutputStream ouvert mais non fermé)
- par extension mauvaise manipulation de fichiers (ex: dans le cas d'un upload d'un fichier envoyé par un formulaire Multipart/form)
- mauvaise gestion des transactions avec la base de données (resultsets ouverts mais non fermés).
- ça peut dépendre encore du type d'interaction que vous avez avec ce File System OCSF2.
- Enfin essayez de mettre à jour vos librairies (.jar) voir si le problème se produit toujours.
[^] # Re: La honte du noyau
Posté par daggett . Évalué à 3.
Voir "man proc" pour les valeurs à mettre effectivement dans /proc/sys/vm/overcommit_memory: (dépend si on a un 2.4 ou un 2.6)
ou modifier la valeur dans /proc/sys/vm/overcommit_ratio
Voir aussi /proc/meminfo, il y a des entrées sur l'utilisation de mémoire "overcommitée" expliquées dans http://www.redhat.com/advice/tips/meminfo.html
[^] # Re: La honte du noyau
Posté par malin . Évalué à 1.
Dans mon experience, Linux est un systeme extremement peu fiable pour tout ce qui concerne la gestion de la memoire aux limites. Quand on a des processes qui ont besoin du maximum de RAM qu'ils peuvent allouer, les Unix standards nous ont habitue a utiliser malloc() et lui faire confiance pour retourner NULL quand il n'y a plus de ressources disponibles. Ce contrat n'est pas respecte sous Linux et ce n'est pas la faute de malloc(), mais bien celle du noyau.
Sur des programmes qui peuvent etre mission-critical (francais?), un tel comportement n'est pas acceptable. La seule facon de s'en sortir est de determiner soi-meme la quantite de memoire disponible a priori sur la machine locale, de surcharger les allocations memoire avec un compteur et d'arreter d'allouer quand le compteur indique une limite atteinte. Les nombreuses discussions qui ont eu lieu avec les developpeurs en charge de la gestion memoire sous Linux se sont terminees en queue de poisson.
Ceci dit, il est rare d'avoir a ecrire des programmes qui ont besoin forcement d'allouer le maximum de memoire disponible dans un environnement critique. Pour la quasi totalite des applications qui tournent sur des desktops, les points decrits ici ne s'appliquent pas. Dans le cas precisement evoque ici, le kernel s'est retrouve aux limites a cause d'une faute de programmation dans une appli Java. Pas de panique donc! Les gens qui ont l'habitude de pousser Linux a ses limites en gestion de memoire doivent juste etre conscients des limitations induites par l'overcommitment.
[^] # Re: La honte du noyau
Posté par Tonton Th (Mastodon) . Évalué à 1.
Plus judicieux il serait, à mon avis, de déterminer la mémoire dont a besoin l'application, et de configurer la machine en conséquence.
de surcharger les allocations memoire avec un compteur
Plus simplement, peut-être voir si tu ne peux pas protéger ton système avec des ulimit mûrement réfléchis...
[^] # Re: La honte du noyau
Posté par arnaudus . Évalué à 2.
[^] # Re: La honte du noyau
Posté par fearan . Évalué à 3.
Quand un malloc te renvoie NULL, tu peux agir en conséquence ( ie vider le cache de ton appli, déclencher un ménage général, fermer tout ce qui n'a pas été utilisé depuis un certain temps, sauver les paramètres de l'appli et quitter.... )
Quand le malloc te donne une adresse mémoire, et que quand tu l'utilise ton process est tué sur place, c'est moyen.
Cependant, c'est un comportement réglable, donc pas ou peu gênant à mon gout, par ailleurs, ulimit permet justement d'éviter les problèmes :)
Il ne faut pas décorner les boeufs avant d'avoir semé le vent
[^] # Re: La honte du noyau
Posté par malin . Évalué à 1.
Quand malloc retourne NULL on peut faire encore beaucoup de choses comme par exemple mapper des espaces disque pour creer son propre swap. Une appli peut aussi avoir envie de profiter du maximum d'espace memoire disponible pour accelerer ses calculs le plus possible. Le probleme de l'overcommitment c'est qu'on ne peut pas compter sur le systeme pour nous dire a un instant T si la prochaine allocation pourra se faire ou bien si elle plantera le systeme.
Pour l'histoire: la discussion qui a precede l'existence de ce patch date de 98. Voir par exemple:
http://lkml.org/lkml/1998/8/14/77
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.