繁体   English   中英

Tomcat8内存泄漏

[英]Tomcat8 memory leak

当我尝试在Java 8上停止tomcat8时,我收到一些内存泄漏错误:

org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [ROOT] appears to have started a thread named [Abandoned connection cleanup thread] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
 java.lang.Object.wait(Native Method)
 java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:142)
 com.mysql.jdbc.AbandonedConnectionCleanupThread.run(AbandonedConnectionCleanupThread.java:40)
23-Jan-2015 08:18:10.202 WARNING [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [ROOT] appears to have started a thread named [pool-5-thread-1] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread


23-Jan-2015 08:18:10.205 SEVERE [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks The web application [ROOT] created a ThreadLocal with key of type [com.util.ThreadLocalProperties$1] (value [com.util.ThreadLocalProperties$1@2fafda6e]) and a value of type [java.util.Properties] (value [{}]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.

ThreadLocalProperties类是:

public class ThreadLocalProperties extends Properties {

    private static final long serialVersionUID = -4260632266508618756L;
    private final ThreadLocal<Properties> localProperties = new ThreadLocal<Properties>() {
        @Override
        protected Properties initialValue() {
            return new Properties();
        }
    };

    public ThreadLocalProperties(Properties properties) {
        super(properties);
    }

    @Override
    public String getProperty(String key) {
        String localValue = localProperties.get().getProperty(key);
        return localValue == null ? super.getProperty(key) : localValue;
    }

    @Override
    public Object setProperty(String key, String value) {
        return localProperties.get().setProperty(key, value);
    }

    public ThreadLocal<Properties> getThreadLocal() {
        return localProperties;
    }
}

我这样开始和停止它:

@WebListener()
public class GeneralListener implements ServletContextListener {

    ThreadLocalProperties threadLocalProperties = new ThreadLocalProperties(System.getProperties());

    @Override
    public void contextDestroyed(ServletContextEvent arg0) {
        threadLocalProperties.getThreadLocal().remove();
    }

    @Override
    public void contextInitialized(ServletContextEvent arg0) {
        System.setProperties(threadLocalProperties);
    }
}

为什么我会得到所有这些内存泄漏错误? 同样,当我运行shutdown时,它不会关闭它,我必须手动终止进程。

怎么了?

没有什么可担心的。 这是一个标准消息tomcat输出,当它检测到应用程序已启动它自己的Thread或创建一个ThreadLocal 如果在关闭时终止线程并在不再需要时删除threadlocals ,那么就没有问题了。

为什么我会得到所有这些内存泄漏错误? 同样,当我运行shutdown时,它不会关闭它,我必须手动终止进程。

我已经看到这种行为,当一个应用程序启动了ScheduledExecutor (但这将发生在任何其他Thread / TheadPool )并且没有在contextDestroyed上关闭它。 因此,请检查您是否在应用程序/服务器停止时关闭了线程。

现在就你的具体问题服务器没有停止的原因:JDBC驱动程序在JVM中作为单例注册,并与所有webapp共享。 更多信息在这里。 解决问题的最佳方法是在Tomcat的/lib文件夹中移动MySQL驱动程序。 如果你不能这样做,你可以尝试这个,但它更像是一个黑客,而不是一个真正的解决方案。

我认为你的问题与类似。 当您重新部署应用程序时,apache会逐步将其部署在system.gc(); 不起作用,在开发阶段进行少量重新部署后,永久生成的空间会变满,并且会出现内存泄漏错误。

重新部署后,请继续重新启动服务器,以便重新启动时清除PermGen空间。

要么

您也可以通过更改服务器中的PermGen空间来解决它。 请访问这里

我希望这能帮到您。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM