Tomcat8内存泄漏 [英] Tomcat8 memory leak

查看:3345
本文介绍了Tomcat8内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

When I try to stop tomcat8 on Java 8, I get a few memory leaks errors:

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类是:

The class ThreadLocalProperties is:

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;
    }
}

我开始和停止它是这样的:

and I start and stop it like this:

@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时,它不会关闭它,我必须手动终止进程。

Why would i get all this memory leaks errors? as well, when I run shutdown, it doesn't shut it down, I have to manually kill the process.

有什么问题?

推荐答案

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

There is nothing to worry about. This is a standard message tomcat outputs when it detects the application has started it's own Thread or created a ThreadLocal. If you terminate the thread on shutdown and remove the threadlocals when they are no longer needed, then there will be no problem.


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

Why would I get all this memory leaks errors? as well, when I run shutdown, it doesn't shut it down, I have to manually kill the process.

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

I've seen this behavior, when an application has started ScheduledExecutor (but this will happen with any other Thread/TheadPool) and didn't shut it down on contextDestroyed. So check if you are shutting down your threads on application/server stop.

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

Now on your concrete problem why the server doesn't stop: JDBC drivers are registered in the JVM as singletons, and are shared with all webapps. More info here. The best solution to your problem is to move the MySQL driver in Tomcat's /lib folder. If you cannot do that you can try this but it's more like a hack than a real solution.

这篇关于Tomcat8内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆