首页 文章

这很可能在Tomcat中造成内存泄漏吗?

提问于
浏览
44

我将tomcat配置为使用不同的外部开源 .

但是,在tomcat运行几分钟后,我得到:

SEVERE:Web应用程序[/ MyProject]使用[java.lang.ThreadLocal]类型的键(值[java.lang.ThreadLocal@1b3f02f])创建了一个ThreadLocal,其值为[org.apache.axis.MessageContext] (值[org.apache.axis.MessageContext@5dbd4e])但在Web应用程序停止时无法将其删除 . 这很可能造成内存泄漏 .

什么可能导致它?

我在哪里看?它可能是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 [java.lang.ThreadLocal@1b5a8e1]) and a value of type [org.mvel2.debug.DebuggerContext] (value [org.mvel2.debug.DebuggerContext@16259fd]) 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 [org.apache.axis.utils.XMLUtils$ThreadLocalDocumentBuilder@84b0b4]) and a value of type [com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl] (value [com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl@16d2cfa]) 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 [com.sun.faces.util.Util$1@16bbac9]) 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 [java.lang.ThreadLocal@1b3f02f]) and a value of type [org.apache.axis.MessageContext] (value [org.apache.axis.MessageContext@5dbd4e]) 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 [org.apache.axis.utils.XMLUtils$ThreadLocalDocumentBuilder@84b0b4]) and a value of type [com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl] (value [com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl@378584]) 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 [{org.hibernate.impl.SessionFactoryImpl@ccc27b=org.springframework.orm.hibernate3.SessionHolder@4f6ada}]) 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 [com.sun.faces.application.ApplicationAssociate$1@1f01fcf]) and a value of type [com.sun.faces.application.ApplicationAssociate] (value [com.sun.faces.application.ApplicationAssociate@1b85528]) 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)

5 回答

  • 0

    消息实际上非常清楚:有些东西会创建 ThreadLocal ,其值为 org.apache.axis.MessageContext - 这是一个很好的提示 . 这很可能意味着Apache Axis框架在自身之后忘记/无法清理 . 例如,在Logback中发生了相同的problem . 你不应该打扰,但向Axis团队报告错误可能是个好主意 .

    Tomcat报告此错误,因为 ThreadLocal 是根据HTTP工作线程创建的 . 您的应用程序已取消部署,但HTTP线程仍然存在 - 这些也是 ThreadLocal . 这可能会导致内存泄漏( org.apache.axis.MessageContext 无法卸载)以及将来重用这些线程时的一些问题 .

    有关详细信息,请参阅:http://wiki.apache.org/tomcat/MemoryLeakProtection

  • 1

    我在CDI @ApplicationScoped bean中向@PreDestroy方法添加了以下内容,当我关闭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");
            }
        }
    
    }
    
  • 2

    密钥"Transactional Resources"看起来像是在没有正确的事务的情况下与数据库通信 . 确保正确配置事务管理,并且不存在不在@Transactional注释下运行的DAO调用路径 . 当您在Controller级别配置事务管理但在计时器中调用DAO或正在使用@PostConstruct注释时,很容易发生这种情况 . 我在这里写了http://georgovassilis.blogspot.nl/2014/01/tomcat-spring-and-memory-leaks-when.html

    编辑:看起来这也是(也是?)spring-data-jpa的一个bug,它已经用v1.4.3修复了 . 我在LockModeRepositoryPostProcessor的spring-data-jpa源代码中查找了它,它设置了“Transactional Resources”键 . 在1.4.3中,它也会再次清除密钥 .

  • 23

    有时这与配置更改有关 . 当我们从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/

  • 6

    当我们使用任何第三方解决方案而不使用处理程序进行清理活动时,会出现此问题 . 对我而言,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

相关问题