2010-07-15 4 views
7

J'ai une application déployée sur Glassfish. Au fil du temps, le nombre de classes chargées monte dans les millions et mon permgen semble augmenter.Ai-je une fuite de classloader JAXB?

Pour aider à résoudre les problèmes, j'ai ajouté ce qui suit à mes arguments jvm. -XX: + PrintGCDetails -XX: + TraceClassUnloading -XX: + TraceClassLoading

Maintenant, lorsque vous regardez la sortie, je vois les mêmes les classes chargées, encore et encore. Fondamentalement, chaque fois qu'un service Web est appelé et JAXB est utilisé pour traiter le fichier XML.

[Loaded com.strikeiron.ZIPCodesInRadius $ JaxbAccessorF_userID de JVM_DefineClass] [Loaded com.strikeiron.ZIPCodesInRadius $ JaxbAccessorF_userID de JVM_DefineClass]

Est-ce que cela indique une fuite? Si oui, comment puis-je le résoudre?

Répondre

6

J'ai trouvé un fil similaire qui décrivait le même problème que j'avais. http://forums.java.net/jive/thread.jspa?threadID=53362

J'ai aussi trouvé un bug à https://java.net/jira/browse/JAXB-581

Fondamentalement, le problème était que je faisais une nouvelle JAXBContext ("your.class.xsd") chaque fois que mon haricot a été invoqué. Selon le bug "Appeler JAXBContext.newInstance (...) implique le rechargement de tout puisque le chargeur de classe actuel ou spécifié doit être (ré) utilisé."

La solution était de créer un singleton qui a bien fonctionné.

public enum JAXBContextSingleton { 

INSTANCE("your.class.xsd"); 
private JAXBContext context; 

JAXBContextSingleton(String classToCreate) { 
    try { 
     this.context = JAXBContext.newInstance(classToCreate); 
    } catch (JAXBException ex) { 
     throw new IllegalStateException("Unbale to create JAXBContextSingleton"); 
    } 
} 

public JAXBContext getContext(){ 
    return context; 
} 

} 

Et utiliser le singleton

JAXBContext context = JAXBContextSingleton.INSTANCE.getContext(); 
0

C'est l'une des raisons pour lesquelles je reste loin de JAXB. Je préfère écrire des classes à marshal et unmarshal qui implémentent javax.xml.bind.Marshaller et javax.xml.bindUnmarshaller, respectivement. Je les écris une fois et ils ont fini. Rien de cette réflexion et de la génération de classe dynamique.