Java Tomcat8内存泄漏

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28105803/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 05:36:42  来源:igfitidea点击:

Tomcat8 memory leak

javatomcatmemory-leaks

提问by Dejell

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

当我尝试在 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] (value [com.util.ThreadLocalProperties@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.

The class ThreadLocalProperties is:

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

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

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.

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

What is wrong?

怎么了?

采纳答案by Svetlin Zarev

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

没有什么可担心的。这是当 tomcat 检测到应用程序已经启动它自己的Thread或创建了一个ThreadLocal. 如果您在关闭时终止线程并在不再需要它们时删除线程局部变量,那么就不会有问题。

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.

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

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.

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

Now on your concrete problemwhy 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 /libfolder. If you cannot do that you can try thisbut it's more like a hack than a real solution.

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

回答by Ravi Chhatrala

I think your problem is similar to this. When you redeploy the app, apache deploys it incrementally on itself where system.gc();do not work and after few redeployment in developing phase the permanent generated space gets full and you get memory leak error.

我认为您的问题与类似。当您重新部署应用程序时,apache 会在system.gc();无法正常工作的地方逐步部署它,并且在开发阶段重新部署几次后,永久生成的空间已满,您会收到内存泄漏错误。

Please keep restarting your server after few redeployment, so the PermGen space can be cleared with a restart.

请在重新部署几次后继续重新启动您的服务器,以便可以通过重新启动来清除 PermGen 空间。

Or

或者

a you can also solve it by changing the PermGen space in server. Please visit here.

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

I hope this will help you.

我希望这能帮到您。