2013-08-15 1 views
2

Open J2EE Web Template - приложение для витрины для калитки - JPA с пружиной и спящим режимом, которая работает на контейнере сервлетов Tomcat7. Его скрипт сборки Maven, как представляется, использует компоненты стандартным образом.Как избежать утечки Classloader с JPA, Hibernate и Spring на Tomcat

Однако на него влияет утечка памяти класса загрузчика приложения, когда он не используется из Tomcat.

Кнопка «Найти утечки» Tomcat подтверждает утечку. При развертывании на Tomcat с опцией VM -XX: + HeapDumpOnOutOfMemoryError сгенерированный кучи кучи можно проанализировать с помощью инструмента анализа памяти Eclipse (MAT). MAT идентифицирует класс java.util.logging.Level$KnownLevel как виновника, который предотвращает сбор мусора.

Отладка KnownLevel конструктора показывает следующую трассировку стеки:.

java.util.logging.Level $ KnownLevel.add (Level.java:477) java.util.logging.Level (Уровень .java: 212) java.util.logging.Level. (Level.java:190) org.jboss.logging.JDKLevel. (JDKLevel.java:35) org.jboss.logging.JDKLevel. (JDKLevel.java : 42) org.jboss.logging.JDKLogger.translate (JDKLogger.java:78) org.jboss.logging.JDKLogger.isEnabled (JDKLogger.java:85) org.jboss.logging.Logger.debugf (Log ger.java:563) org.jboss.logging.LoggerProviders.find (LoggerProviders.java:37) org.jboss.logging.LoggerProviders. (LoggerProviders.java:32) org.jboss.logging.Logger.getLogger (Logger.java:2163) org.jboss.logging.Logger.getMessageLogger (Logger.java:2259) org.jboss.logging.Logger.getMessageLogger (Logger.java:2214) org.hibernate.ejb.Ejb3Configuration. (Ejb3Configuration.java:144) org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory (HibernatePersistence.java:74) org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory (LocalContainerEntityManagerFactoryBean.java:268) org.springframework.orm.jpa .AbstractEntityManagerFactoryBean.afterPropertiesSet (Ab stractEntityManagerFactoryBean.java:310) org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods (AbstractAutowireCapableBeanFactory.java:1514) org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean (AbstractAutowireCapableBeanFactory.java:1452) орг .springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean (AbstractAutowireCapableBeanFactory.java:519) org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean (AbstractAutowireCapableBeanFactory.java:456) org.springframework.beans.factory.support .AbstractBeanFactory $ 1.getObject (AbstractBeanFactory.java:294) org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton (DefaultSingletonBeanRegistry.jav а: 225) org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean (AbstractBeanFactory.java:291) org.springframework.beans.factory.support.AbstractBeanFactory.getBean (AbstractBeanFactory.java:193) org.springframework .beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons (DefaultListableBeanFactory.java:567) org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization (AbstractApplicationContext.java:913) org.springframework.context.support.AbstractApplicationContext.refresh (AbstractApplicationContext .java: 464) org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext (ContextLoader.java:385) org.springframework.web.context.ContextLoader.initWebApplicationContext (ContextLoader.java:284) org.springframework.web.context.ContextLoaderListener.contextInitialized (ContextLoaderListener.java:111) org.apache.catalina.core.StandardContext.listenerStart (StandardContext.java:4939)

Если я правильно понял Classloader leaks: the dreaded "java.lang.OutOfMemoryError: PermGen space" exception, тогда следует ожидать утечку этого класса.

Каким будет рекомендованный метод, чтобы избежать этого, или что было бы альтернативным Spring/JPA шаблоном веб-приложения на Tomcat?

ответ

1

Я видел эту же утечку памяти WebApp на Tomcat7 + OpenJPA2.4.1 + ValidationAPI1.x + зимует-валидатор-5.2.1 + JBoss-logging.jar

Проблема действительно JBoss-logging.jar создает подкласс java.util.logging.Level экземпляров. Не может быть проблемой, если jar предоставлен контейнером J2EE, но произойдет с распространением mywebapp/WEB-INF/lib. I have created a fork of package для отключения подкласса. Проблемы ушли, и горячие перераспределения webapp работают нормально.

Heapdump корневого пути GC указывает на источник проблемы, подкласс JDKLevel хранит webapp в памяти, и вскоре JVM заканчивается из памяти PermGen.

this  - value: org.apache.catalina.loader.WebappClassLoader #2 
<- <classLoader>  - class: org.jboss.logging.JDKLevel, value: org.apache.catalina.loader.WebappClassLoader #2 
    <- <class>  - class: org.jboss.logging.JDKLevel, value: org.jboss.logging.JDKLevel class JDKLevel 
    <- levelObject  - class: java.util.logging.Level$KnownLevel, value: org.jboss.logging.JDKLevel #6 
    <- [1]  - class: java.lang.Object[], value: java.util.logging.Level$KnownLevel #12 
    <- elementData  - class: java.util.ArrayList, value: java.lang.Object[] #5160 (10 items) 
     <- value  - class: java.util.HashMap$Entry, value: java.util.ArrayList #3532 
     <- [0]  - class: java.util.HashMap$Entry[], value: java.util.HashMap$Entry #21639 
     <- table  - class: java.util.HashMap, value: java.util.HashMap$Entry[] #280 (16 items) 
     <- intToLevels (sticky class)  - class: java.util.logging.Level$KnownLevel, value: java.util.HashMap #375 

редактировать Создано JBoss Jira билет на эту ошибку (https://issues.jboss.org/browse/JBLOGGING-118)

+0

Ваша работа высоко ценится. Не могли бы вы рассмотреть возможность отслеживания проблемы с проектом jboss logging, чтобы ваша работа в конечном итоге стала частью исходного дистрибутива? Я предлагаю это, потому что я столкнулся с дополнительными проблемами загрузчика классов, для которых я хотел бы создать примеры тестов на кости, которые не попадают в ЭТУ проблему. – user250343

+0

@ user250343 Выполнено, что уже однажды я нашел эту утечку памяти (https://github.com/jboss-logging/jboss-logging/pull/21). Я не знаю, видел ли соответствующий разработчик мой запрос. – Whome

1

Конфигурирование системы ведения журнала, отличной от java.util.logging, например. Logback.

Если никакого ведения журнала не настроено вообще или не настроено java.util.logging, ведение журнала jboss создаст утечку загрузчика класса через ошибку JDK Level.known can leak memory. См. Трассировку стека в вопросе, где jboss logging создает пользовательский java.util.logging.Level.

Смежные вопросы