EDIT:CORBA + Tomcat 6 + Webapp classloader fuite
J'ai trouvé fuite classloader dans mon webapplication. Cela se résume à une bibliothèque tierce qui initialise CORBA via le service de nommage COS de JNDI et n'expose pas un appel à fermer proprement le contexte de JNDI. Cela laisse des threads liés à CORBA et d'autres ressources référençant mon chargeur de classe webapp et l'empêchant d'être récupéré. Cela entraîne une erreur OutOfMemory: PermGen après quelques redéployages/rechargements.
Pour l'instant j'ai augmenté la mémoire PermGen dans JVM et cela rend les intervalles entre les arrêts du serveur plus longs. Ce n'est évidemment pas une solution mais une solution de contournement (et une mauvaise d'ailleurs).
Je suppose que ma question est de savoir s'il est possible de fermer proprement le contexte JNDI sans tenir de référence. Mon instinct me dit non, mais peut-être que je ne connais pas une caractéristique magique de JNDI qui me permettrait de saisir ce contexte.
Ainsi, la façon dont la bibliothèque 3ème partie initialise objets CORBA est quelque chose le long de ces lignes (gestion des exceptions et d'autres détails entendue rectifier par souci de concision):
private CorbaObjectAggregate initCorba() {
InitialContext ctx = null;
CorbaObjectAggregate corbaObjects = new CorbaObjectAggregate();
ORB orb = null;
Properties env = getContextEnvironment();
String[] args = null;
orb = ORB.init(args, null);
env.put("java.naming.corba.orb", orb);
ctx = new InitialContext(env);
//a bunch of object lookups follow
corbaObjects.someCorbaObjectReference = (SomeCorbaObjectClass) ctx.lookup("somePaht");
return corbaObjects;
}
Ainsi, la référence à ctx
est parti après cette méthode fin de l'exécution.
J'ai essayé d'arrêter les filets manuellement mais cela n'a pas permis de réparer la fuite. Je suppose qu'il y a d'autres ressources de corba sur classloader. Je suppose que je pourrais essayer de les traquer dans une méthode de nettoyage et libérer le classloader de cette façon, mais j'espérais une solution plus propre. Pour plus de clarté, la bibliothèque 3rd Party est fermée et je ne peux pas vraiment le changer. Ce n'est pas non plus une option viable pour obtenir de l'aide de la part de l'entreprise.
* (c'est pas une réponse, d'où le commentaire) * ... Personnellement, je demanderais au développeur de l'API tierce pour réparer leur gâchis. En attendant, vous pouvez * atténuer * le problème en utilisant un PermGen plus grand ou en utilisant une JVM qui ne serait pas une Oracle/Sun, car PermGen, IIRC, est une spécificité Oracle/Sun. * (qui dit oh les souvenirs: je me souviens avoir découvert par moi-même un terrible problème de Tomcat + Sun JVM + Hibernate permgen à l'époque où pratiquement aucune information ne pouvait être trouvée sur le sujet;) * À l'époque nous "réparions" notre problème Résine IIRC (il y a vraiment plusieurs années). – TacticalCoder
Malheureusement, les développeurs tiers n'existent pas :). C'est un système hérité avec lequel notre application doit s'intégrer. Mais cela mis à part, je ne suis pas sûr que le problème se trouve directement dans la bibliothèque. Comme je l'ai mentionné, le thread est en fait créé par le sous-système CORBA, donc j'imagine que toute bibliothèque utilisant CORBA déclencherait la création de ce thread. Cela dit, je ne suis en aucun cas un expert de la CORBa. Malheureusement, changer de serveur d'application est non-non non plus. – artur
comme une solution de contournement qui peut vous faire gagner du temps, vous pouvez passer la JVM Oracle/SUn l'argument qui crée un plus grand PermGen ... Quelque chose comme ceci: -XX: MaxPermSize = 512m C'est bien sûr une solution de contournement temporaire. Qu'en est-il de l'option "Find Leaks" de Tomcat 6 * (vous pouvez l'appeler par exemple dans la webapp du gestionnaire Tomcat), trouve-t-elle la même fuite? – TacticalCoder