Мне развернули приложение на Glassfish. Со временем число загруженных подъемов классов в миллионы и мой permgen, кажется, увеличивается.
Чтобы помочь диагностировать, я добавил следующее к своим jvm аргументам.-XX: + PrintGCDetails-XX: + TraceClassUnloading-XX: + TraceClassLoading
Теперь при наблюдении вывода, я вижу, что те же классы загружаются много раз. В основном каждый раз веб-сервис называют, и JAXB используется для обработки xml.
[Загруженный com.strikeiron. ZIPCodesInRadius$JaxbAccessorF_userID от JVM_DefineClass] [Загруженный com.strikeiron. ZIPCodesInRadius$JaxbAccessorF_userID от JVM_DefineClass]
Это указывает на утечку? Раз так, как я разрешаю его?
Я нашел похожую ветку, в которой описывалась та же проблема, с которой я столкнулся. http://forums.java.net/jive/thread.jspa?threadID=53362
Я также обнаружил ошибку на https://github.com/javaee/jaxb-v2/issues/581
По сути, проблема заключалась в том, что я создавал новый JAXBContext ("your.class.xsd") каждый раз, когда вызывается мой bean-компонент. . Согласно ошибке «Вызов JAXBContext.newInstance (...) подразумевает перезагрузку всего, так как текущий или указанный загрузчик классов должен (повторно) использоваться»
. Решением было создать синглтон, который отлично работал .
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;
}
}
И использовать синглтон
JAXBContext context = JAXBContextSingleton.INSTANCE.getContext();
Это одна из причин, по которой я держусь подальше от JAXB. Я бы предпочел писать классы для маршалинга и демаршалинга, которые реализуют javax.xml.bind.Marshaller
и javax.xml.bindUnmarshaller
соответственно. Я пишу их один раз, и они готовы. Никакого отражения и генерации динамических классов.