Récemment, j'ai rencontré cette erreur dans mon application Web:
java.lang.OutOfMemoryError: espace PermGen
Il s'agit d'une application Hibernate / JPA + IceFaces / JSF typique fonctionnant sur Tomcat 6 et JDK 1.6. Apparemment, cela peut se produire après le redéploiement d'une application à quelques reprises.
Qu'est-ce qui la cause et que peut-on faire pour l'éviter? Comment résoudre le problème?
Réponses:
La solution était d'ajouter ces drapeaux à la ligne de commande JVM au démarrage de Tomcat:
Pour ce faire, arrêtez le service tomcat, puis accédez au répertoire Tomcat / bin et exécutez tomcat6w.exe. Sous l'onglet "Java", ajoutez les arguments à la boîte "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 devez exécuter:
où servicename est le nom du serveur tel qu'il apparaît dans services.msc
Source: commentaire d'Orx sur les réponses agiles d'Eric .
la source
Vous feriez 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. (Ainsi, l'activation du déchargement de classe pour tomcat peut résoudre le problème.) Si vos applications génèrent et compilent des classes lors de l'exécution, il est plus probable qu'elles nécessitent un pool de mémoire plus grand que celui par défaut.
la source
Les erreurs PermGen du serveur d'applications qui se produisent après plusieurs déploiements sont probablement causées par des références détenues par le conteneur dans les chargeurs de classe de vos anciennes applications. Par exemple, l'utilisation d'une classe de niveau de journalisation personnalisée entraînera la tenue de références par le chargeur de classe du serveur d'applications. Vous pouvez détecter ces fuites entre chargeurs de classes en utilisant des outils d'analyse JVM modernes (JDK6 +) tels que jmap et jhat pour voir quelles classes continuent d'être conservées dans votre application, et en repensant ou en éliminant leur utilisation. Les suspects habituels sont les bases de données, les enregistreurs et les autres bibliothèques au niveau du framework de base.
Voir les fuites de Classloader: l'exception redoutée "java.lang.OutOfMemoryError: PermGen space" , et en particulier son article de suivi .
la source
Les gens commettent souvent des erreurs en pensant que l'espace de tas et l'espace de 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 permgen.
Les causes courantes d'OutofMemory dans PermGen sont ClassLoader. Chaque fois qu'une classe est chargée dans JVM, toutes ses métadonnées, ainsi que Classloader, sont conservées dans la zone PermGen et elles seront récupérées lorsque le Classloader qui les a chargées est prêt pour la collecte des ordures. Dans le cas où Classloader a une fuite de mémoire, toutes les classes chargées par celui-ci resteront en mémoire et provoqueront une permofen outofmemory une fois que vous le répéterez plusieurs fois. L'exemple classique est Java.lang.OutOfMemoryError: PermGen Space dans Tomcat .
Il existe maintenant 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. Augmentez la taille de PermGen Space en utilisant les paramètres JVM
-XX:MaxPermSize
et-XX:PermSize
.Vous pouvez également consulter 2 Solution de Java.lang.OutOfMemoryError en Java pour plus de détails.
la source
-XX:MaxPermSize and -XX:PermSize
?? Je ne trouve pascatalina.bat
. Ma version tomcat est5.5.26
.Utilisez le paramètre de ligne de commande
-XX:MaxPermSize=128m
pour une machine virtuelle Java Sun (en substituant évidemment 128 à la taille dont vous avez besoin).la source
Essayez
-XX:MaxPermSize=256m
et si cela persiste, essayez-XX:MaxPermSize=512m
la source
XX:MaxPermSize=1024m
:)J'ai ajouté
-XX: MaxPermSize = 128m
(vous pouvez expérimenter ce qui fonctionne le mieux) aux arguments VM car j'utilise l'ide d'éclipse. Dans la plupart des JVM, PermSize par défaut est d'environ 64 Mo, ce qui manque de mémoire s'il y a trop de classes ou un grand nombre de chaînes dans le projet.Pour l'éclipse, il est également décrit à la réponse .
ÉTAPE 1 : Double-cliquez sur le serveur tomcat dans l' onglet Serveurs
ÉTAPE 2 : Ouvrez Launch Conf et ajoutez
-XX: MaxPermSize = 128m
à la fin des arguments VM existants .la source
J'ai buté ma tête contre ce problème lors du déploiement et du retrait d'une application Web complexe, et j'ai pensé ajouter une explication et ma solution.
Lorsque je déploie une application sur Apache Tomcat, un nouveau ClassLoader est créé pour cette application. Le ClassLoader est ensuite utilisé pour charger toutes les classes de l'application, et lors du retrait, tout est censé bien disparaître. Cependant, en réalité, ce n'est pas aussi simple.
Une ou plusieurs des classes créées au cours de la vie de l'application Web contiennent une référence statique qui, quelque part le long de la ligne, fait référence au ClassLoader. Comme la référence est à l'origine statique, aucune quantité de récupération de place ne nettoiera cette référence - le ClassLoader et toutes les classes qu'il est chargé sont là pour rester.
Et après quelques redéploiements, nous rencontrons OutOfMemoryError.
Maintenant, c'est devenu un problème assez grave. Je pourrais m'assurer que Tomcat est redémarré après chaque redéploiement, mais cela supprime l'ensemble du serveur, plutôt que simplement l'application redéployée, ce qui n'est souvent pas faisable.
Au lieu de cela, j'ai mis en place une solution dans le code, qui fonctionne sur Apache Tomcat 6.0. Je n'ai testé sur aucun autre serveur d'applications et je dois souligner qu'il est très probable que cela ne fonctionne pas sans modification sur un autre serveur d'applications .
Je voudrais également dire que personnellement, je déteste ce code, et que personne ne devrait l'utiliser comme une «solution rapide» si le code existant peut être modifié pour utiliser des méthodes d'arrêt et de nettoyage appropriées . La seule fois où cela devrait être utilisé, c'est s'il existe une bibliothèque externe dont votre code dépend (dans mon cas, c'était un client RADIUS) qui ne fournit pas un moyen de nettoyer ses propres références statiques.
Quoi qu'il en soit, avec le code. Cela doit être appelé au point où l'application ne se déploie pas - comme la méthode destroy d'un servlet ou (la meilleure approche) la méthode contextDestroyed d'un ServletContextListener.
la source
Le
java.lang.OutOfMemoryError: PermGen
message d'espace indique que la zone de mémoire de la génération permanente est épuisée.Toutes les applications Java sont autorisées à utiliser une quantité limitée de mémoire. La quantité exacte de mémoire que votre application particulière peut utiliser est spécifiée au démarrage de l'application.
La mémoire Java est séparée en différentes régions qui peuvent être vues dans l'image suivante:
Metaspace: un nouvel espace mémoire est né
La JVM JDK 8 HotSpot utilise maintenant la mémoire native pour la représentation des métadonnées de classe et s'appelle Metaspace; similaire à Oracle JRockit et IBM JVM.
La bonne nouvelle est que cela signifie plus de
java.lang.OutOfMemoryError: PermGen
problèmes d'espace et plus besoin de régler et de surveiller cet espace mémoire à l'aide de Java_8_Download ou supérieur.la source
1) Augmenter la taille de la mémoire PermGen
La première chose que l'on peut faire est d'agrandir la taille de l'espace de stockage de génération permanente. Cela ne peut pas être fait avec les arguments JVM habituels –Xms (définir la taille initiale du segment) et –Xmx (définir la taille maximale du segment), car, comme mentionné, l'espace de segment de génération permanent est entièrement distinct de l'espace de segment Java standard et ces arguments sont définis l'espace pour cet espace de tas Java standard. Cependant, il existe des arguments similaires qui peuvent être utilisés (au moins avec les jvms Sun / OpenJDK) pour augmenter la taille du tas de génération permanente:
La valeur par défaut est 64 m.
2) Activer le balayage
Une autre façon de s'en occuper pour de bon est d'autoriser le déchargement des classes pour que votre PermGen ne s'épuise jamais:
Des trucs comme ça ont fait de la magie pour moi dans le passé. Une chose cependant, il y a un compromis de performance significatif dans leur utilisation, car les balayages permgen feront comme 2 demandes supplémentaires pour chaque demande que vous faites ou quelque chose dans ce sens. Vous devrez équilibrer votre utilisation avec les compromis.
Vous pouvez trouver les détails de cette erreur.
http://faisalbhagat.blogspot.com/2014/09/java-outofmemoryerror-permgen.html
la source
Alternativement, vous pouvez passer à JRockit qui gère le permgen différemment du jvm du soleil. Il a généralement de meilleures performances également.
http://www.oracle.com/technetwork/middleware/jrockit/overview/index.html
la source
java.lang.OutOfMemoryError: There is insufficient native memory
place.J'ai eu le problème dont nous parlons ici, mon scénario est eclipse-helios + tomcat + jsf et ce que vous faisiez est de faire un déploiement d'une application simple sur tomcat. Je montrais le même problème ici, je l'ai résolu comme suit.
Dans eclipse, allez dans l' onglet serveurs double-cliquez sur le serveur enregistré dans mon cas tomcat 7.0, il ouvre mon serveur de fichiers Informations générales d'enregistrement. Dans la section "Informations générales" cliquez sur le lien "Ouvrir la configuration de lancement" , cela ouvre l'exécution des options du serveur dans l'onglet Arguments des arguments VM ajoutés à la fin de ces deux entrées
et prêt.
la source
La réponse la plus simple de nos jours est d'utiliser Java 8.
Il ne réserve plus de mémoire exclusivement pour l'espace PermGen, permettant à la mémoire PermGen de se mélanger avec le pool de mémoire normal.
Gardez à l'esprit que vous devrez supprimer tous les
-XXPermGen...=...
paramètres de démarrage JVM non standard si vous ne voulez pas que Java 8 se plaigne de ne rien faire.la source
Dans la zone de texte Options Java, ajoutez cette ligne:
la source
Une erreur d'espace de génération permanente se produit en raison de l'utilisation d'un grand espace plutôt que de l'espace fourni par jvm pour exécuter le code.
La meilleure solution à ce problème dans les systèmes d'exploitation UNIX consiste à modifier une configuration sur le fichier bash. Les étapes suivantes résolvent le problème.
Exécutez la commande
gedit .bashrc
sur le terminal.Créez une
JAVA_OTPS
variable avec la valeur suivante:Enregistrez le fichier bash. Exécutez la commande exec bash sur le terminal. Redémarrez le serveur.
J'espère que cette approche fonctionnera sur votre problème. Si vous utilisez une version Java inférieure à 8, ce problème se produit parfois. Mais si vous utilisez Java 8, le problème ne se produit jamais.
la source
L'augmentation de la taille de la génération permanente ou la modification des paramètres GC n'aidera PAS si vous avez une vraie fuite de mémoire. Si votre application ou une bibliothèque tierce qu'elle utilise, les chargeurs de classe de fuites, la seule solution réelle et permanente est de trouver cette fuite et de la corriger. Il existe un certain nombre d'outils qui peuvent vous aider, l'un des plus récents est Plumbr , qui vient de publier une nouvelle version avec les capacités requises.
la source
De plus, si vous utilisez log4j dans votre application Web, consultez ce paragraphe dans la documentation de log4j .
Il semble que si vous utilisez
PropertyConfigurator.configureAndWatch("log4j.properties")
, vous causez des fuites de mémoire lorsque vous annulez le déploiement de votre application Web.la source
J'ai une combinaison de mise en veille prolongée + Eclipse RCP, essayé d' utiliser
-XX:MaxPermSize=512m
et-XX:PermSize=512m
il semble fonctionner pour moi.la source
Set
-XX:PermSize=64m -XX:MaxPermSize=128m
. Plus tard, vous pouvez également essayer d'augmenterMaxPermSize
. J'espère que ça marchera. La même chose fonctionne pour moi. Le réglageMaxPermSize
n'a pas fonctionné pour moi.la source
J'ai essayé plusieurs réponses et la seule chose qui a finalement fait le travail était cette configuration pour le plugin du compilateur dans le pom:
j'espère que celui-ci aide.
la source
jrockita résolu cela aussi pour moi; cependant, j'ai remarqué que les temps de redémarrage des servlets étaient bien pires, donc même s'il était meilleur en production, c'était une sorte de ralentissement dans le développement.
la source
La configuration de la mémoire dépend de la nature de votre application.
Qu'est-ce que tu fais?
Quel est le montant des transactions nécessaires?
Combien de données chargez-vous?
etc.
etc.
etc
Vous pourriez probablement profiler votre application et commencer à nettoyer certains modules de votre application.
Tomcat a un déploiement à chaud mais il consomme de la mémoire. Essayez de redémarrer votre conteneur de temps en temps. Vous aurez également besoin de connaître la quantité de mémoire nécessaire pour fonctionner en mode production, cela semble un bon moment pour cette recherche.
la source
Ils disent que la dernière version de Tomcat (6.0.28 ou 6.0.29) gère beaucoup mieux la tâche de redéploiement des servlets .
la source
Je rencontre exactement le même problème, mais malheureusement aucune des solutions suggérées n'a vraiment fonctionné pour moi. Le problème ne s'est pas produit pendant le déploiement, et je ne faisais aucun déploiement à chaud.
Dans mon cas, le problème s'est produit à chaque fois au même moment lors de l'exécution de mon application web, lors de la connexion (via hibernate) à la base de données.
Ce lien (également mentionné précédemment) a fourni suffisamment d'informations internes pour résoudre le problème. Le déplacement du pilote jdbc- (mysql) hors du WEB-INF et dans le dossier jre / lib / ext / semble avoir résolu le problème. Ce n'est pas la solution idéale, car la mise à niveau vers un JRE plus récent vous obligerait à réinstaller le pilote. Un autre candidat qui pourrait causer des problèmes similaires est log4j, vous pouvez donc aussi déplacer celui-ci
la source
La première étape dans ce cas consiste à vérifier si le GC est autorisé à décharger des classes de PermGen. La JVM standard est plutôt conservatrice à cet égard - les classes naissent pour vivre éternellement. Ainsi, une fois chargées, les classes restent en mémoire même si aucun code ne les utilise plus. Cela peut devenir un problème lorsque l'application crée dynamiquement de nombreuses classes et que les classes générées ne sont pas nécessaires pour des périodes plus longues. Dans un tel cas, il peut être utile d'autoriser la JVM à décharger les définitions de classe. Cela peut être réalisé en ajoutant un seul paramètre de configuration à vos scripts de démarrage:
Par défaut, ce paramètre est défini sur false et pour l'activer, vous devez définir explicitement l'option suivante dans les options Java. Si vous activez CMSClassUnloadingEnabled, GC va également balayer PermGen et supprimer les classes qui ne sont plus utilisées. Gardez à l'esprit que cette option ne fonctionnera que lorsque UseConcMarkSweepGC est également activé à l'aide de l'option ci-dessous. Donc, lorsque vous exécutez ParallelGC ou, Dieu nous en préserve, Serial GC, assurez-vous que vous avez défini votre GC sur CMS en spécifiant:
la source
Attribuer plus de mémoire à Tomcat n'est PAS la bonne solution.
La bonne solution consiste à effectuer un nettoyage une fois le contexte détruit et recréé (le déploiement à chaud). La solution est d'arrêter les fuites de mémoire.
Si votre serveur Tomcat / Webapp vous indique que l'échec de l'annulation de l'enregistrement des pilotes (JDBC) a échoué, annulez leur enregistrement. Cela arrêtera les fuites de mémoire.
Vous pouvez créer un ServletContextListener et le configurer dans votre web.xml. Voici un exemple de ServletContextListener:
Et ici, vous le configurez dans votre web.xml:
la source
«Ils» sont faux car j'utilise 6.0.29 et j'ai le même problème même après avoir défini toutes les options. Comme Tim Howland l'a dit plus haut, ces options ne font que repousser l'inévitable. Ils me permettent de redéployer 3 fois avant de frapper l'erreur au lieu de chaque fois que je redéploie.
la source
Si vous obtenez cela dans l'IDE de l'éclipse, même après avoir défini les paramètres
--launcher.XXMaxPermSize
,-XX:MaxPermSize
etc., toujours si vous obtenez la même erreur, il est très probable que l'éclipse utilise une version boguée de JRE qui aurait été installée par certains applications tierces et définies par défaut. Ces versions de buggy ne récupèrent pas les paramètres PermSize et donc peu importe ce que vous définissez, vous continuez à obtenir ces erreurs de mémoire. Donc, dans votre eclipse.ini, ajoutez les paramètres suivants:Assurez-vous également de définir le JRE par défaut dans les préférences de l'éclipse sur la version correcte de java.
la source
La seule façon qui a fonctionné pour moi était avec la JVM JRockit. J'ai MyEclipse 8.6.
Le tas de la JVM stocke tous les objets générés par un programme Java en cours d'exécution. Java utilise l'
new
opérateur pour créer des objets et la mémoire pour les nouveaux objets est allouée sur le tas au moment de l'exécution. Le garbage collection est le mécanisme de libération automatique de la mémoire contenue par les objets qui ne sont plus référencés par le programme.la source
J'avais un problème similaire. Le mien est JDK 7 + Maven 3.0.2 + Struts 2.0 + projet basé sur l'injection de dépendance Google GUICE.
Chaque fois que j'essayais d'exécuter la
mvn clean package
commande, il montrait l'erreur suivante et "BUILD FAILURE" se produisaitJ'ai essayé tous les trucs et astuces utiles ci-dessus, mais malheureusement, aucun n'a fonctionné pour moi. Ce qui a fonctionné pour moi est décrit étape par étape ci-dessous: =>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
élément puis un<argLine>
sous-élément dans lequel passer-Xmx512m -XX:MaxPermSize=256m
comme indiqué ci-dessous =><configuration> <argLine>-Xmx512m -XX:MaxPermSize=256m</argLine> </configuration>
J'espère que ça aide, bonne programmation :)
la source