1233 votes

Traitement de l'erreur "java.lang.OutOfMemoryError : Espace permGen".

Récemment, j'ai rencontré cette erreur dans mon application web :

java.lang.OutOfMemoryError : Espace PermGen

Il s'agit d'une application typique Hibernate/JPA + IceFaces/JSF fonctionnant sous Tomcat 6 et JDK 1.6. Apparemment, cela peut se produire après avoir redéployé une application plusieurs fois.

Quelles en sont les causes et que peut-on faire pour l'éviter ? Comment résoudre le problème ?

0 votes

Je me suis battu contre ça pendant des heures, mais je n'ai pas de bonnes nouvelles. Voir ma question connexe : stackoverflow.com/questions/1996088/ Il se peut qu'il y ait encore une fuite de mémoire, par exemple, les classes ne sont pas collectées parce que votre WebAppClassLoader n'est pas collecté (il a une référence externe qui n'est pas effacée). Augmenter le PermGen ne fera que retarder l'OutOfMemoryError, et permettre la collecte des classes est une condition préalable, mais ne collectera pas les classes si leur chargeur de classe a encore des références à elles.

0 votes

J'ai obtenu cette erreur en ajoutant afficher taglib . La suppression de ce dernier a également résolu l'erreur. Pourquoi so ?

0 votes

Et comment êtes-vous tombé dessus ?

567voto

Chris Points 336

La solution consistait à ajouter ces drapeaux à la ligne de commande de la JVM lors du démarrage de Tomcat :

-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled

Vous pouvez le faire en arrêtant le service Tomcat, puis en allant dans le répertoire Tomcat/bin et en exécutant tomcat6w.exe. Sous l'onglet "Java", ajoutez les arguments dans la case "Options Java". Cliquez sur "OK", puis redémarrez le service.

Si vous obtenez une erreur le service spécifié n'existe pas en tant que service installé vous devriez vous présenter :

tomcat6w //ES//servicename

nom du service est le nom du serveur tel qu'il est affiché dans services.msc

Source : commentaire d'orx sur Les réponses agiles d'Eric .

39 votes

L'article ci-dessous suggère -XX:+UseConcMarkSweepGC et -XX:MaxPermSize=128m également. my.opera.com/karmazilla/blog/2007/03/13/

30 votes

-XX:+CMSPermGenSweepingEnabled Cette option réduit les performances. Elle fait que chaque requête prend trois fois plus de temps que d'habitude sur nos systèmes. A utiliser avec précaution.

10 votes

A fonctionné pour moi - merci - je fais cela sur Ubuntu 10.10 avec Tomcat6 - j'ai créé un nouveau fichier : /usr/share/tomcat6/bin/setenv.sh et j'y ai ajouté la ligne suivante : JAVA_OPTS="-Xms256m -Xmx512m -XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled" - J'ai redémarré tomcat en utilisant : sudo /etc/init.d/tomcat6 start

251voto

Tu ferais mieux d'essayer -XX:MaxPermSize=128M plutôt que -XX:MaxPermGen=128M .

Je ne peux pas dire l'utilisation précise de ce pool de mémoire, mais cela a à voir avec le nombre de classes chargées dans la JVM. (Si vos applications génèrent et compilent des classes en cours d'exécution, il est plus probable que vous ayez besoin d'un pool de mémoire plus grand que celui par défaut.

153voto

Les erreurs PermGen du serveur d'applications qui surviennent après plusieurs déploiements sont très probablement dues à des références détenues par le conteneur dans les classloaders de vos anciennes applications. Par exemple, l'utilisation d'une classe de niveau de journal personnalisée entraînera la détention de références par le classloader du serveur d'applications. Vous pouvez détecter ces fuites inter-classeur en utilisant des outils d'analyse modernes (JDK6+) de la JVM, tels que jmap et jhat, afin d'identifier les classes qui continuent d'être utilisées dans votre application, et de revoir ou d'éliminer leur utilisation. Les suspects habituels sont les bases de données, les enregistreurs et d'autres bibliothèques de base.

Voir Fuites de chargeur de classe : le redoutable "java.lang.OutOfMemoryError : PermGen space" exception et surtout son post de suivi .

68voto

Peter Points 1

Les gens commettent souvent l'erreur de penser que l'espace du tas et l'espace du permgen sont identiques, ce qui n'est pas du tout vrai. Vous pouvez avoir beaucoup d'espace restant dans le tas mais vous pouvez toujours manquer de mémoire dans le permgen.

Les causes courantes de OutofMemory dans PermGen sont ClassLoader. Chaque fois qu'une classe est chargée dans la JVM, toutes ses métadonnées, ainsi que le Classloader, sont conservés dans la zone PermGen et ils seront collectés lorsque le Classloader qui les a chargés est prêt pour la collecte des déchets. Dans le cas où le Classloader a une fuite de mémoire, toutes les classes qu'il a chargées resteront en mémoire et provoqueront le dépassement de la mémoire de PermGen si vous le répétez plusieurs fois. L'exemple classique est Java.lang.OutOfMemoryError:Espace permGen dans Tomcat .

Il y a deux façons de résoudre ce problème :
1. Trouvez la cause de la fuite de mémoire ou s'il y a une fuite de mémoire.
2. Augmenter la taille de l'espace PermGen en utilisant le paramètre JVM -XX:MaxPermSize y -XX:PermSize .

Vous pouvez également vérifier 2 Solution de l'erreur Java.lang.OutOfMemoryError en Java pour plus de détails.

3 votes

Comment passer le paramètre -XX:MaxPermSize and -XX:PermSize ? ? Je n'arrive pas à trouver catalina.bat . Ma version de tomcat est 5.5.26 .

0 votes

Comment trouver les fuites de mémoire du chargeur de classe ? Recommandez-vous un outil ?

0 votes

@amit pour les recommandations d'outils, voir la réponse du wiki communautaire sur cette question.

43voto

user17163 Points 473

Utilisez le paramètre de ligne de commande -XX:MaxPermSize=128m pour une JVM Sun (en remplaçant évidemment 128 par la taille dont vous avez besoin).

9 votes

Le seul problème est que vous ne faites que retarder l'inévitable - à un moment donné, vous manquerez de marge de manœuvre là aussi. C'est une excellente solution pragmatique, mais elle ne résout pas le problème de façon permanente.

0 votes

La même chose se produit dans Eclipse et chaque fois que vous avez beaucoup de chargement de classe dynamique. les classloaders ne sont pas éliminés et vivent dans la génération permanente pour l'éternité.

1 votes

J'étais à court de PermGen lors de l'exécution d'une tâche Hudson particulièrement importante... cela a réglé le problème pour moi.

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