25

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.

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

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?

Dejell
  • 13,947
  • 40
  • 146
  • 229

2 Answers2

26

There is nothing to worry about. This is a standard message tomcat outputs when it detects the application has started its 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.

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.

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 from the webapp's WEB-INF/lib into Tomcat's /lib folder. If you cannot do that you can try this but it's more like a hack than a real solution.

EricS
  • 569
  • 1
  • 3
  • 15
Svetlin Zarev
  • 14,713
  • 4
  • 53
  • 82
  • Thanks. Yes it really helped! the interesting thing is, that if I deploy my app called Algo, and have this in server.xml WEB-INF/web.xml it would deploy Algo war both to Algo folder and ROOT folder! – Dejell Jan 23 '15 at 11:48
  • 3
    Moving the mysql driver into Tomcat's /lib folder didn't work for me. – Neets Oct 20 '15 at 14:02
  • Did you remove the driver from /WEB-INF/lib ? Aslo you will get this message if your application is starting threads and is not stopping them. – Svetlin Zarev Oct 20 '15 at 14:15
1

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.

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

Or

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

I hope this will help you.

Community
  • 1
  • 1
Ravi Chhatrala
  • 324
  • 4
  • 14
  • I don't re-deploy the server. I ./shutdown and ./startup it. I believe that it clears the perm size no? – Dejell Jan 23 '15 at 09:19
  • also, when I tried added perm size definition to tomcat8 I get a warning that it's being ignored – Dejell Jan 23 '15 at 09:20
  • Are you perhaps also running Java 8? I'm not 100% sure, but I think that the permgen space has become irrelevant from that release forward. I see no reason why these informational warning messages that Tomcat is logging has anything to do with permgen space, nor are they anything to worry about if you're hard rebooting the server. – Gimby Jan 23 '15 at 09:29
  • I am not saying about redeploying your server, I am talking redeploying with respect to your web app, which you are trying to run on apache tomcat server. The multiple times you save and build your app then it will create a .war file right? and that will be redeployed incrementally. (This will throw memory leak error after few builds.) – Ravi Chhatrala Jan 23 '15 at 10:14
  • 1
    @Dejel Try changing the PermGen space manually: To set the environment variable on Windows, create a setenv.bat manually, and put it into the `${tomcat-folder}\bin` folder. `${tomcat-folder}\bin\setenv.bat` set `JAVA_OPTS=-Dfile.encoding=UTF-8 -Xms128m -Xmx1024m -XX:PermSize=64m -XX:MaxPermSize=256m` or more. It won't show any warning further regarding this and it will not ignore as well. – Ravi Chhatrala Jan 23 '15 at 10:30
  • yes I am running java 8, and it became irrelevant there – Dejell Jan 23 '15 at 11:49