Y a-t-il un moyen d'éviter les fuites de mémoire dans Tomcat?
cette question s'adresse à tous ceux qui ont déjà testé le bouton "Find leaks" dans le Gestionnaire Tomcat et obtenu des résultats du genre:
les applications web suivantes ont été stoppées (reloaded, undeployed), mais leurs classes des éditions précédentes sont toujours chargées en mémoire, provoquant ainsi une fuite de mémoire (utiliser un profileur pour confirmer):
/qui fuit-app-name
je suppose que cela a quelque chose à faire avec cette erreur "Perm Gen space" vous obtenez souvent avec de fréquents redéploiements.
donc ce que je vois dans jconsole quand je suis déployé c'est que mes classes chargées vont d'environ 2k à 5k. On pourrait penser qu'un non-déploiement devrait les ramener à 2k, mais ils restent à 5k.
j'ai également essayé d'utiliser les options suivantes JVM:
-XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC -XX:+CMSPermGenSweepingEnabled
j'ai vu des baisses très mineures dans la quantité D'espace disponible utilisé mais pas ce à quoi je m'attendais et le nombre de classes chargées n'a pas chuté.
alors y a-t-il un moyen de configurer Tomcat ou de concevoir votre application pour mieux décharger sur un undeployment? Ou sommes-nous bloqués avec le redémarrage du serveur après quelques sessions de débogage majeures?
Tomcat version sortie:
Version serveur: Apache Tomcat / 6.0.29
Construction du serveur: 19 juillet 2010 1458
Numéro de serveur: 6.0.0.29
Nom du système D'exploitation: Windows 7
Version OS: 6.1
Architecture: x86
Version JVM: 1.6.0_18-b07
JVM vendeur: Sun Microsystems Inc.
mise à jour:
grâce à la réponse de celias j'ai décidé de creuser un peu plus et je pense que j'ai déterminé le coupable à être dans mon application grâce à CXF, Spring et JAXB.
après avoir appris à profiler une application Java, j'ai pointé le profileur sur Tomcat et j'ai pris quelques dumps en tas et des snapshots pour voir à quoi ressemblaient les objets et les classes en mémoire. J'ai découvert que certaines des énumérations de mon schéma XML utilisées dans mes classes générées par CXF/JAXB (wsdl2java) persistaient après un non-déploiement. D'après mon tas de ferraille, on dirait que les objets étaient attachés à une carte. Avertissement: je reconnais que je suis encore un peu vert avec le profilage et tracer l'arbre d'appel d'un objet peut être difficile en Java.
aussi, je dois mentionner que je n'ai même pas invoqué le service, juste déployé puis non déployé. Les objets eux-mêmes semblaient être chargés par réflexion initiée à partir du ressort lors du déploiement. Je crois que j'ai suivi la convention pour la mise en place D'un service CXF au printemps. Donc je ne suis pas sûr à 100% que ce soit Spring / CXF, JAXB, ou la réflexion est la faute de.
comme note latérale: l'application en question est un service web utilisant Spring/CXF et le XML se trouve être un schéma assez complexe (une extension de NIEM ).
2 réponses
Si vous voulez vous assurer de ne pas causer de fuites, vous devez faire ce qui suit:
- assurez-vous que votre application web n'utilise pas de classes java qui sont dans les bibliothèques partagées de conteneur web. Si vous avez des bibliothèques partagées, assurez-vous qu'il n'y a pas de références fortes aux objets dans ces bibliothèques
- éviter d'utiliser des variables statiques, en particulier sur les objets java comme HashTable, Sets, etc. Si vous en avez besoin, assurez-vous que vous appelez supprimer pour libérer les objets avec les cartes, listes...
voici aussi un bon article sur ThreadLocal et MemoryLeaks - http://blog.arendsen.net/index.php/2005/02/22/threadlocals-and-memory-leaks-revisited/
Tomcat 7 est censé apporter des améliorations dans ce domaine. Voir caractéristiques D'Apache Tomcat 7 , section intitulée plus de fuites!
ils croient qu'Ils peuvent maintenant faire face à beaucoup de fuites de mémoire causées par les applications web. Malheureusement, il est encore en version bêta.
à part ça, je peux dire que j'ai fait la même expérience et que je n'ai pas trouvé de solution. Le déploiement nécessite habituellement redémarrer Tomcat après. Je n'ai aucune idée de qui est le coupable: mon application web, Tomcat, Hibernate, Tapestry ou plusieurs d'entre eux.