Возможно ли это, чтобы создать утечку памяти в Tomcat?
Я сконфигурировал tomcat для работы с другим внешним открытым исходным кодом.
Однако после того, как tomcat работает в течение нескольких минут, я получаю:
SEVERE: веб-приложение [/MyProject] создало ThreadLocal с ключ типа [java.lang.ThreadLocal] (значение [[email protected]]) и значение типа [org.apache.axis.MessageContext] (значение [[email protected]]), но не удалось удалить его, когда веб-приложение было остановлено. Это, скорее всего, создаст утечка памяти.
Что может вызвать это?
Где мне искать? Может ли это быть datapooling на Tomcat?
И что это означает "Темы в Tomcat"?
EDITED
Вот мой полный след. Приложение, похоже, перезагружает свой контекст во время его работы - и я не знаю, почему!
Mar 13, 2011 10:56:12 PM org.apache.catalina.core.StandardContext reload
INFO: Reloading this Context has started
Mar 13, 2011 10:56:12 PM org.apache.catalina.core.StandardWrapper unload
INFO: Waiting for 1 instance(s) to be deallocated
Mar 13, 2011 10:56:13 PM org.apache.catalina.core.StandardWrapper unload
INFO: Waiting for 1 instance(s) to be deallocated
Mar 13, 2011 10:56:14 PM org.apache.catalina.core.StandardWrapper unload
INFO: Waiting for 1 instance(s) to be deallocated
Mar 13, 2011 10:56:14 PM org.apache.catalina.core.ApplicationContext log
INFO: Closing Spring root WebApplicationContext
Mar 13, 2011 10:56:15 PM org.apache.catalina.loader.WebappClassLoader clearReferencesJdbc
SEVERE: The web application [/MyProject] registered the JBDC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
Mar 13, 2011 10:56:15 PM org.apache.catalina.loader.WebappClassLoader clearReferencesJdbc
SEVERE: The web application [/MyProject] registered the JBDC driver [oracle.jdbc.driver.OracleDriver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
Mar 13, 2011 10:56:15 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/MyProject] appears to have started a thread named [NioSocketAcceptor-1] but has failed to stop it. This is very likely to create a memory leak.
Mar 13, 2011 10:56:15 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/MyProject] appears to have started a thread named [NioProcessor-1] but has failed to stop it. This is very likely to create a memory leak.
Mar 13, 2011 10:56:15 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/MyProject] appears to have started a thread named [NioProcessor-4] but has failed to stop it. This is very likely to create a memory leak.
Mar 13, 2011 10:56:15 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/MyProject] appears to have started a thread named [bitronix-disk-force-batcher] but has failed to stop it. This is very likely to create a memory leak.
Mar 13, 2011 10:56:15 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/MyProject] appears to have started a thread named [bitronix-scheduler] but has failed to stop it. This is very likely to create a memory leak.
Mar 13, 2011 10:56:15 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/MyProject] is still processing a request that has yet to finish. This is very likely to create a memory leak. You can control the time allowed for requests to finish by using the unloadDelay attribute of the standard Context implementation.
Mar 13, 2011 10:56:15 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/MyProject] appears to have started a thread named [NioProcessor-7] but has failed to stop it. This is very likely to create a memory leak.
Mar 13, 2011 10:56:15 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/MyProject] appears to have started a thread named [NioProcessor-2] but has failed to stop it. This is very likely to create a memory leak.
Mar 13, 2011 10:56:15 PM org.apache.catalina.loader.WebappClassLoader clearThreadLocalMap
SEVERE: The web application [/MyProject] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [[email protected]]) and a value of type [org.mvel2.debug.DebuggerContext] (value [[email protected]]) but failed to remove it when the web application was stopped. This is very likely to create a memory leak.
Mar 13, 2011 10:56:15 PM org.apache.catalina.loader.WebappClassLoader clearThreadLocalMap
SEVERE: The web application [/MyProject] created a ThreadLocal with key of type [org.apache.axis.utils.XMLUtils.ThreadLocalDocumentBuilder] (value [[email protected]]) and a value of type [com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl] (value [[email protected]cfa]) but failed to remove it when the web application was stopped. This is very likely to create a memory leak.
Mar 13, 2011 10:56:15 PM org.apache.catalina.loader.WebappClassLoader clearThreadLocalMap
SEVERE: The web application [/MyProject] created a ThreadLocal with key of type [null] (value [[email protected]]) and a value of type [java.util.HashMap] (value [{com.sun.faces.patternCache={ = }}]) but failed to remove it when the web application was stopped. This is very likely to create a memory leak.
Mar 13, 2011 10:56:15 PM org.apache.catalina.loader.WebappClassLoader clearThreadLocalMap
SEVERE: The web application [/MyProject] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [[email protected]]) and a value of type [org.apache.axis.MessageContext] (value [[email protected]]) but failed to remove it when the web application was stopped. This is very likely to create a memory leak.
Mar 13, 2011 10:56:15 PM org.apache.catalina.loader.WebappClassLoader clearThreadLocalMap
SEVERE: The web application [/MyProject] created a ThreadLocal with key of type [org.apache.axis.utils.XMLUtils.ThreadLocalDocumentBuilder] (value [[email protected]]) and a value of type [com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl] (value [[email protected]84]) but failed to remove it when the web application was stopped. This is very likely to create a memory leak.
Mar 13, 2011 10:56:15 PM org.apache.catalina.loader.WebappClassLoader clearThreadLocalMap
SEVERE: The web application [/MyProject] created a ThreadLocal with key of type [org.springframework.core.NamedThreadLocal] (value [Transactional resources]) and a value of type [java.util.HashMap] (value [{[email protected][email protected]}]) but failed to remove it when the web application was stopped. This is very likely to create a memory leak.
Mar 13, 2011 10:56:15 PM org.apache.catalina.loader.WebappClassLoader clearThreadLocalMap
SEVERE: The web application [/MyProject] created a ThreadLocal with key of type [null] (value [[email protected]]) and a value of type [com.sun.faces.application.ApplicationAssociate] (value [[email protected]]) but failed to remove it when the web application was stopped. This is very likely to create a memory leak.
2011-03-13 22:57:27,734 ERROR ( ContextLoader.java:220) - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager' defined in class path resource [applicationContext-hibernate.xml]: Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [applicationContext-hibernate.xml]: Invocation of init method failed; nested exception is java.lang.OutOfMemoryError: Java heap space
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:106)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1325)
Ответы
Ответ 1
Сообщение на самом деле довольно ясно: что-то создает ThreadLocal
со значением типа org.apache.axis.MessageContext
- это отличный намек. Скорее всего, это означает, что инфраструктура Apache Axis забыла/не смогла очистить после себя. Такая же проблема возникла, например, в журнале. Вы не должны сильно беспокоиться, но сообщение об ошибке для команды Axis может быть хорошей идеей.
Tomcat сообщает об этой ошибке, поскольку ThreadLocal
создается для потоков HTTP-рабочих. Ваше приложение не развернуто, но HTTP-потоки остаются - и эти ThreadLocal
. Это может привести к утечке памяти (org.apache.axis.MessageContext
не может быть выгружен) и некоторые проблемы, когда эти потоки будут повторно использоваться в будущем.
Подробнее см.: http://wiki.apache.org/tomcat/MemoryLeakProtection
Ответ 2
Я добавил следующий метод @PreDestroy в свой CDI @ApplicationScoped bean, и когда я завершаю TomEE 1.6.0 (tomcat7.0.39, на сегодняшний день), он очищает локаторы потоков.
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package pf;
import java.lang.ref.WeakReference;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* @author Administrator
*
* google-gson issue # 402: Memory Leak in web application; comment # 25
* https://code.google.com/p/google-gson/issues/detail?id=402
*/
public class ThreadLocalImmolater {
final Logger logger = LoggerFactory.getLogger(ThreadLocalImmolater.class);
Boolean debug;
public ThreadLocalImmolater() {
debug = true;
}
public Integer immolate() {
int count = 0;
try {
final Field threadLocalsField = Thread.class.getDeclaredField("threadLocals");
threadLocalsField.setAccessible(true);
final Field inheritableThreadLocalsField = Thread.class.getDeclaredField("inheritableThreadLocals");
inheritableThreadLocalsField.setAccessible(true);
for (final Thread thread : Thread.getAllStackTraces().keySet()) {
count += clear(threadLocalsField.get(thread));
count += clear(inheritableThreadLocalsField.get(thread));
}
logger.info("immolated " + count + " values in ThreadLocals");
} catch (Exception e) {
throw new Error("ThreadLocalImmolater.immolate()", e);
}
return count;
}
private int clear(final Object threadLocalMap) throws Exception {
if (threadLocalMap == null)
return 0;
int count = 0;
final Field tableField = threadLocalMap.getClass().getDeclaredField("table");
tableField.setAccessible(true);
final Object table = tableField.get(threadLocalMap);
for (int i = 0, length = Array.getLength(table); i < length; ++i) {
final Object entry = Array.get(table, i);
if (entry != null) {
final Object threadLocal = ((WeakReference)entry).get();
if (threadLocal != null) {
log(i, threadLocal);
Array.set(table, i, null);
++count;
}
}
}
return count;
}
private void log(int i, final Object threadLocal) {
if (!debug) {
return;
}
if (threadLocal.getClass() != null &&
threadLocal.getClass().getEnclosingClass() != null &&
threadLocal.getClass().getEnclosingClass().getName() != null) {
logger.info("threadLocalMap(" + i + "): " +
threadLocal.getClass().getEnclosingClass().getName());
}
else if (threadLocal.getClass() != null &&
threadLocal.getClass().getName() != null) {
logger.info("threadLocalMap(" + i + "): " + threadLocal.getClass().getName());
}
else {
logger.info("threadLocalMap(" + i + "): cannot identify threadlocal class name");
}
}
}
Ответ 3
Ключ "Транзакционные ресурсы" выглядит так, будто вы разговариваете с базой данных без надлежащей транзакции. Убедитесь, что управление транзакциями настроено правильно, и не существует пути обращения к DAO, который не запускается под аннотацией @Transactional. Это может произойти, когда вы настроили управление транзакциями на уровне контроллера, но вызываете DAO в таймере или используете аннотации @PostConstruct. Я написал его здесь http://georgovassilis.blogspot.nl/2014/01/tomcat-spring-and-memory-leaks-when.html
Изменить: похоже, что это (также?) ошибка с spring -data-jpa, исправленная с v1.4.3. Я просмотрел его в источниках spring -data-jpa LockModeRepositoryPostProcessor, который устанавливает ключ "Транзакционные ресурсы". В 1.4.3 он снова очищает ключ.
Ответ 4
Иногда это связано с изменениями конфигурации. Когда мы обновились с Tomncat 6.0.14 до 6.0.26, мы увидели нечто подобное. вот решение
http://www.skill-guru.com/blog/2010/08/22/tomcat-6-0-26-shutdown-reports-a-web-application-created-a-threadlocal-threadlocal-has-been-forcibly-removed/
Ответ 5
Эта проблема возникает, когда мы используем какое-либо третье решение, без использования обработчиков для активизации очистки.
Для меня это происходило для EhCache. Мы использовали EhCache в нашем проекте для кэширования.
И часто мы видели следующую ошибку в журналах
SEVERE: The web application [/products] appears to have started a thread named [products_default_cache_configuration] but has failed to stop it. This is very likely to create a memory leak.
Aug 07, 2017 11:08:36 AM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/products] appears to have started a thread named [Statistics Thread-products_default_cache_configuration-1] but has failed to stop it. This is very likely to create a memory leak.
И мы часто замечаем, что tomcat не смог выполнить ошибку OutOfMemory во время разработки, где мы делали бэкэнд-изменения и развертывали приложение несколько раз для отражения наших изменений.
Это исправление, которое мы сделали
<listener>
<listener-class>
net.sf.ehcache.constructs.web.ShutdownListener
</listener-class>
</listener>
Итак, я пытаюсь сделать, это проверить документацию сторонних библиотек, которые вы используете. Они должны предоставлять некоторые механизмы для очистки потоков во время остановки. Что вам нужно использовать в своем приложении.
Не нужно повторно изобретать колесо, если оно не предусмотрено ими. Худший случай - предоставить вам собственную реализацию.
Ссылка для завершения EHCache
http://www.ehcache.org/documentation/2.8/operations/shutdown.html