Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tomcat8 memory leak

Tags:

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?

like image 745
Dejell Avatar asked Jan 23 '15 08:01

Dejell


People also ask

What is memory leak in Tomcat?

Cause 1 - Memory LeaksBecause the PermGen has a finite size, reloading the flawed application just a handful of times can trigger an OutOfMemoryError, or OOME. Eliminating retained references to the web application class loader will allow Garbage Collection to function properly, preventing these errors.

How much memory should I allocate to Tomcat?

In general, a minimal install requires 4GB for the OS, the tomcat heap XMS setting (default 4GB), 2GB for Retain and any memory the database requires if installed. In all cases, when only the worker is installed the memory is automatically tuned to 3GB.

What is the main cause of memory leaks in application Linkedin?

1. Memory Leak Through static Fields. The first scenario that can cause a potential memory leak is heavy use of static variables. In Java, static fields have a life that usually matches the entire lifetime of the running application (unless ClassLoader becomes eligible for garbage collection).


2 Answers

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.

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 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.

like image 193
Svetlin Zarev Avatar answered Sep 23 '22 17:09

Svetlin Zarev


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.

like image 31
Ravi Chhatrala Avatar answered Sep 22 '22 17:09

Ravi Chhatrala