41 votes

Problèmes PermGen avec Lift et Jetty

Je développe sur la plateforme standard Lift (maven et jetty). J'obtiens ceci de manière répétée (une fois tous les deux jours) :

Exception in thread "7048009@qtp-3179125-12" java.lang.OutOfMemoryError: PermGen space
2009-09-15 19:41:38.629::WARN:  handle failed
java.lang.OutOfMemoryError: PermGen space

Ceci dans mon environnement de développement. Ce n'est pas un problème car je peux continuer à redémarrer le serveur. En déploiement, je n'ai pas ces problèmes, donc ce n'est pas un vrai problème. Je suis juste curieux.

Je ne connais pas très bien la JVM. Je pense que j'ai raison de penser que la mémoire de génération permanente est pour des choses comme les classes et les chaînes internées ? Ce dont je me souviens est un peu mélangé avec le modèle de mémoire .NET...

Quelle est la raison de ce phénomène ? Les valeurs par défaut sont-elles excessivement basses ? Est-ce que c'est lié à tous les objets auxiliaires que Scala doit créer pour les objets Function et autres objets FP similaires ? Chaque fois que je redémarre Jetty avec un nouveau code écrit (toutes les quelques minutes), j'imagine qu'il recharge les classes, etc. Mais même ainsi, il ne peut pas y en avoir autant, n'est-ce pas ? Et la JVM ne devrait-elle pas être capable de gérer un grand nombre de classes ?

Santé

Joe

44voto

VonC Points 414372

À partir de ce post:

Cette exception s'est produite pour une raison simple :
l' permgenspace est où les propriétés de la classe, comme les méthodes, les champs, les annotations, et aussi des variables statiques, etc. sont stockées dans la machine virtuelle Java, mais cet espace a la particularité de ne pas être nettoyé par le garbage collector. Donc, si votre application utilise ou crée beaucoup de classes (je pense dynamique des générations de classes), les chances sont que vous avez rencontré ce problème. Voici quelques solutions qui m'a aidé à me débarrasser de cette exception :

  • -XX:+CMSClassUnloadingEnabled : ce paramètre permet de collecte des ordures dans la permgenspace
  • -XX:+CMSPermGenSweepingEnabled : permet le garbage collector pour enlever même les classes à partir de la mémoire
  • -XX:PermSize=64M -XX:MaxPermSize=128M : soulève la quantité de mémoire allouée à la permgenspace

Peut-être que cela pourrait aider.

Edition juillet 2012 (près de 3 ans plus tard):

Ondra Žižka commentaires (et j'ai mis à jour la réponse ci-dessus):

JVM 1.6.0_27 dit: Merci d'utiliser:

  • CMSClassUnloadingEnabled (Si la classe de déchargement activé lors de l'utilisation de CMS GC)
  • à la place de CMSPermGenSweepingEnabled dans le futur

Voir l'intégralité de la JVM Hotspot Options - La référence complète de manière plus.

12voto

Ondra Žižka Points 8262

Si vous voyez ceci lorsque vous exécutez mvn jetty:run , fixer le MAVEN_OPTS .

Pour Linux :

export MAVEN_OPTS="-XX:+CMSClassUnloadingEnabled -XX:PermSize=256M -XX:MaxPermSize=512M"
mvn jetty:run

Pour Windows :

set "MAVEN_OPTS=-XX:+CMSClassUnloadingEnabled -XX:PermSize=256M -XX:MaxPermSize=512M"
mvn jetty:run

Tout devrait bien se passer maintenant. Si ce n'est pas le cas, augmentez -XX:MaxPermSize .

Vous pouvez également les adapter en permanence à votre environnement.

  • Pour Linux, ajoutez l'élément export ligne à ~/.bashrc

  • Pour Windows, appuyez sur Win-key + PrintScreen et aller Advanced > Environment . Voir aussi http://support.microsoft.com/kb/310519 .

3voto

col Points 229

Cela est dû au rechargement des classes comme vous l'avez suggéré. Si vous utilisez de nombreuses bibliothèques, etc., la somme des classes augmentera rapidement à chaque redémarrage. Essayez de surveiller votre instance jetty avec VisualVM pour avoir une vue d'ensemble de la consommation de mémoire lors du rechargement.

2voto

Jorge Ortiz Points 3374

La liste de diffusion ( http://groups.google.com/group/liftweb/ ) est le forum d'assistance officiel de Lift, et c'est là que vous pourrez obtenir une meilleure réponse. Je ne connais pas les détails de votre configuration de développement (vous ne donnez pas beaucoup de détails), mais je suppose que vous rechargez votre guerre dans Jetty sans la redémarrer. Lift n'effectue pas de génération dynamique de classes (comme le suggère VonC ci-dessus), mais Scala compile chaque fermeture comme une classe séparée. Si vous ajoutez et supprimez des fermetures à votre code pendant plusieurs jours, il est possible que trop de classes soient chargées et jamais déchargées et qu'elles occupent de l'espace en perm. Je vous suggère d'activer les options de la JVM mentionnées par VonC ci-dessus et de voir si elles vous aident.

1voto

Miguel Ping Points 9013

La génération permanente est l'endroit où la JVM place les éléments qui ne seront probablement pas collectés (par les éboueurs), comme les chargeurs de classe personnalisés.

En fonction de ce que vous déployez, le paramètre perm gen peut être bas. Certaines applications et/ou combinaisons de conteneurs contiennent des fuites de mémoire, de sorte que lorsqu'une application est déployée, certains éléments tels que les chargeurs de classe ne sont pas collectés, ce qui a pour effet de remplir le Perm Space et de générer l'erreur que vous rencontrez.

Malheureusement, la meilleure option dans ce cas est de maximiser l'espace perm avec le drapeau jvm suivant (exemple pour une taille de perm de 192m) :

-XX:MaxPermSize=192M (or 256M)

L'autre option consiste à s'assurer que le conteneur ou le cadre ne fuit pas la mémoire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X