Comme déjà mentionné, vous rencontrez probablement des fuites de chargeurs de classe. Pour une raison quelconque, vos classes ne sont pas déchargées. Cela peut se produire pour deux raisons
- Les objets desdites classes existent toujours sur le tas, les objets référencent toujours leur classe, ou
- Le chargeur de classe est référencé quelque part, pour une raison quelconque, les chargeurs de classe référencent leurs classes afin de ne pas les charger deux fois
Il n'y a pas de solution universelle à ce problème. Un outil utile pour vous aider à trouver la cause principale est l' outil Eclipse Memory Analyzer Tool , que vous pouvez appliquer à un vidage de tas de votre machine virtuelle Java (vous pouvez activer les vidages de tas sur les MOO avec l'option -XX: + HeapDumpOnOutOfMemoryError). Commencez peut-être à rechercher des objets java.lang.Class à partir de votre application Web pour voir pourquoi ils sont maintenus en vie. Malheureusement, PermGen ne fait normalement pas partie d'un vidage de tas JVM, vous ne pouvez donc qu'essayer de trouver des artefacts corrélatifs dans le reste du tas (les objets de classe ne sont pas stockés dans PermGen si je ne me trompe pas, seul le code d'octets réel l'est, veuillez corrigez-moi si je me trompe).
HTH.
Edit:
Dave Cheney suggère dans un commentaire que les objets java.lang.Class font en effet partie de PermGen, et ne sont pas inclus dans un vidage de tas de hotspot normal. Sauf si vous disposez d'une machine virtuelle Java qui écrit ces informations dans le vidage de tas, vous aurez besoin d'une approche différente. Vous pouvez toujours rechercher des instances de vos objets, mais si vous perdez des classes / chargeurs de classe (ils s'impliquent malheureusement tous les deux), il semble que vous devez rechercher d'autres signes (objets de métadonnées de JBoss, etc.).
La cause sous-jacente est les références aux classes qui ont été rejetées et qui fuient en dehors de leur chargeur de classe, empêchant la JVM de décharger ces classes du perm gen. Ces drapeaux que vous utilisez peut entraîner la machine virtuelle Java à des classes de purge agressive qui sont unloadable, mais il ne résoudra pas le problème sous - jacent.
Il y a une bonne et complexe explication ici
la source
La cause de l'erreur PermGen OutOfMemory est le redéploiement de l'application. La cause sous-jacente est la fuite d'objets de classe dans PermGen à partir des redéploiements.
Bien entendu, la solution consiste à redémarrer la JVM après un certain nombre de redéploiements.
Il s'agit d'un problème très difficile à résoudre totalement, bien qu'avec certains détournements, vous puissiez souvent apporter de grandes améliorations. Voici par où commencer: lorsque votre application Web est arrêtée, assurez-vous que:
Ce sont certaines des choses qui peuvent provoquer un objet Class à être piégé dans PermGen.
Notez également que toutes les JVM (ou toutes les versions de JVM) ne seront pas des objets de classe GC dans PermGen. Si vous exécutez une JVM ou une version d'une JVM qui ne contiendra pas d'objets de classe GC dans PermGen, votre seul choix est de redémarrer la JVM après un certain nombre de redéploiements. Cela ne s'applique probablement pas à vous, compte tenu des options JVM que vous mentionnez.
la source