JBoss 7, java.lang.OutOfMemoryError: PermGen space

j'ai frappé cette erreur où L'utilisation CPU va à ses limites et JBoss a besoin d'un redémarrage (java.lang.OutOfMemoryError: PermGen space).

j'ai trouvé une solution pour la version plus ancienne de JBoss pour augmenter le MaxPermSize. Je suppose que la même chose vaut pour JBoss7.

quelle valeur serait assez bonne pour ne plus avoir de problèmes? Y a-t-il un moyen de s'éloigner définitivement de ce problème (comme disons utiliser une VM différente comme JRockit)?

25
demandé sur Craig Ringer 2012-07-25 13:17:37
la source

4 ответов

puisque cela se produit après plusieurs transferts, il semble que vous avez rencontré un chargeur de classe de fuite, un genre commun de permgen de fuite.

ces belles bêtes se produisent en raison de références normales (non faibles) des objets possédés par le conteneur aux objets qui sont des instances de classes chargées à partir de l'application classloader. Si ces références ne sont pas effacées sur undeploy Il ya encore une chaîne de référence forte à classloader de l'application, de sorte qu'il les classes chargées ne peuvent pas être libérées.

une cause commune est les collections statiques dans les classes de conteneurs qui ont des références non statiques aux classes d'application ajoutées.

JBoss AS 7 a quelques dispositions assez fortes dans son système de module pour prévenir les fuites de classloader, donc je suis surpris que vous ayez réussi à en déclencher une. Je n'ai pas vu de fuite de classloader depuis que J'ai déménagé à AS7 de Glassfish.

L'augmentation de MaxPermSize vous fera gagner du temps, mais il ne sera pas se débarrasser du problème.

vous avez vraiment besoin de comprendre pourquoi le classloader fuit. Le faire, c'est "fun". Vous aimez les impôts, les défauts intermittents, et le nettoyage de la douche, Non? Voir les liens dans le premier par pour certains blogs qui vous permettra de commencer à traquer la fuite vers le bas. Fondamentalement, vous aurez envie d'utiliser VisualVM et OQL à creuser pour les références de votre application chargeur de classe, ou de prendre un tas de vidage et d'utiliser jhat (partie du JDK) pour trouver référence. Quoi qu'il en soit, l'idée est de trouver où se trouve la chaîne de référence solide du serveur d'applications à votre classloader via les instances de vos classes d'applications.

Alternativement, il peut aider à prendre une copie de votre application, puis démarrer l'extraction de bits d'elle jusqu'à ce que la fuite s'en va. Vous pouvez dire si elle fuit en connectant VisualVM ou une autre surveillance à la VM du serveur d'application et en regardant pour voir si PermGen augmente après deux ou plusieurs cycles de déploiement/undeploy. Envisager d'automatiser le cycles de déploiement et de déploiement. Réduisez la cause de la fuite à une petite partie de votre application et/ou à l'une de ses dépendances et produisez un petit cas de test autonome, puis soumettez-le comme un rapport de bogue sur (a) JBoss AS 7, depuis AFAIK il est destiné à arrêter ce qui se passe et (b) le coupable qui tient la référence.

si vous réduisez la cause à une dépendance qui est emmagasinée dans votre archive de déploiement, le déplacer dans un module JBoss AS 7 peut résoudre le problème. Créer un JBoss module pour elle, de déployer la modules répertoire de AS7, et ajouter une dépendance à votre déploiement via votre Manifest.MF ou par jboss-deployment-structure.xml. Voir le documentation sur le chargeur de classe AS7.

C'est pourquoi le report du projet Jigsaw me rend triste. Java besoins un système de module fort qui se débarrasse de cette merde.

53
répondu Craig Ringer 2012-07-31 11:51:03
la source

le paramètre VM est:

-XX:MaxPermSize=256M

juste assez grand pour ne pas atteindre la limite.

D'une manière générale, la mémoire permanente est utilisée pour les objets associés aux Classes et aux cordes internes. Vous ne devriez pas vous enfuir à moins d'avoir utilisé beaucoup de cours différents.

7
répondu Bohemian 2012-07-25 13:27:21
la source

Nous avons eu à faire exactement la même chose et malheureusement visualvm n'a pas fait beaucoup pour nous.

nous avons fini par utiliser eclipse mat pour analyser le dump tas généré sur crash et ensuite vérifié le leak suspects rapport qui nous a dit qu'il y avait beaucoup de ModuleClassLoader cas de fuites.

en cliquant sur une des instances de l'onglet overview puis en sélectionnant merge shortest paths to GC roots+ exclude weak references nous a donné notre coupable qui ne permettait pas ces ModuleClassLoader cas GC'ed!

https://smalldata.tech/blog/2015/09/29/détection-java-permgen-mémoire-fuite

4
répondu Victor Parmar 2017-03-30 21:21:42
la source

Pourquoi ça arrive?

l'erreur "PermGen" se produit lorsque la machine virtuelle Java est à court de la mémoire dans la génération permanente. Rappelons que Java a un éboueur générationnel, avec quatre générations: eden, jeune, vieux et permanent. Dans la génération eden, les objets sont très courts vécu et la collecte des ordures est rapide et souvent. La jeune génération se compose d'objets qui ont survécu à la génération eden (ou a été poussé en bas à young parce que le eden generation était pleine à l'époque de la collecte des ordures dans la jeune génération est moins fréquents, mais arrive encore à intervalles réguliers (à condition que votre application fait réellement quelque chose et attribue des objets chaque maintenant et puis). L'ancienne génération, eh bien, vous avez compris. Il contient objets qui ont survécu à la jeune génération ou qui ont été abattus, la collecte des ordures est encore moins fréquente, mais elle peut quand même avoir lieu. Et enfin, le permanent génération. C'est pour les objets que l' machine virtuelle a décidé de souscrire à la vie éternelle - qui est precicely le cœur du problème. Les objets de la génération permanente ne sont jamais nettoyés; c'est, dans des circonstances normales, lorsque la jvm est lancée avec des paramètres de ligne de commande normaux. Donc, ce que se produit lorsque vous redéployez votre application web est, que votre fichier WAR est déballé et ses fichiers de classe sont chargés dans le jvm. Et voici le chose: presque toujours se termine en la génération permanente... (occupé de: http://rlogiacco.blogspot.com/2009/02/jboss-and-permgen-outofmemoryerror.html)

Voici quelques conseils :

Utilisez ces paramètres pour votre JVM. ils disent au ramasseur d'ordures d'invoquer son algorithme aussi sur le PermGen.

set JAVA_OPTS=-Xms512m -Xmx1024m 
-XX:PermSize=512m 
-XX:MaxPermSize=1024m 
-XX:+UseConcMarkSweepGC 
-XX:+CMSPermGenSweepingEnabled 
-XX:+CMSClassUnloadingEnabled 
  • CMSPermGenSweepingEnabled le réglage inclut le PermGen dans un la collecte des ordures exécuter. Par défaut, L'espace PermGen est jamais inclus dans la collecte des ordures (et donc grandit sans limites).
  • CMSClassUnloadingEnabled le réglage indique les ordures PermGen balayage de la collection pour prendre des mesures sur les objets de la classe. Par défaut, la classe les objets bénéficient d'une exemption, même lorsque L'espace PermGen est visité lors d'une collection de fourrages.

redémarrez votre JBOSS car chaque fois que vous déployez l'application, vous augmentez la quantité de données dans le PermGen.

Vous pouvez utilisez également JRocket JVM au lieu de Sun JVM. il n'a pas de PermGen dans son algorithme de collecteur D'ordures.

1
répondu Kamal SABBAR 2016-10-25 13:40:51
la source

Autres questions sur