Guice + Tomcat potential memory leak
Asked Answered
I

3

12

I have just started using Google Guice with my Tomcat webapp, and have noticed the following in the catalina.out file whenever the WAR file is undeployed:

May 16, 2011 5:37:24 PM org.apache.catalina.startup.HostConfig checkResources INFO: Undeploying context [/app]

May 16, 2011 5:37:24 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads SEVERE: A web application appears to have started a thread named [com.google.inject.internal.util.$Finalizer] but has failed to stop it. This is very likely to create a memory leak.

May 16, 2011 5:37:24 PM org.apache.catalina.loader.WebappClassLoader clearThreadLocalMap SEVERE: A web application created a ThreadLocal with key of type [null] (value [com.google.inject.internal.InjectorImpl$1@10ace8d]) and a value of type [java.lang.Object[]] (value [[Ljava.lang.Object;@7e9bed]) but failed to remove it when the web application was stopped. To prevent a memory leak, the ThreadLocal has been forcibly removed.

Does anyone know what causes this, or how I can stop it from happening?

I have only followed the instructions from here http://code.google.com/docreader/#p=google-guice&s=google-guice&t=ServletModule

... and haven't done anything fancy with it yet. I just have 2 servlets and a filter.

Thanks!

Impressionism answered 17/5, 2011 at 0:46 Comment(0)
L
3

If you are getting this when you shutdown the webapp, I wouldn't worry too much. This type of resource leak on app. shutdown is common. They do become a problem when you frequently do hot deploys (i.e. un-deploy many times without killing the JVM), but they won't be problematic when a cold deploy is done (un-deploy/deploy is done while killing the JVM before re-deploy).

A common tactic is that you do hot-deploys during development (as they are typically faster than cold-deploys), and only do a cold deploy when the resource leak starts to affect your performance. Then, in production you do a cold deploy on every deploy. Given the number of code/libraries that has this type of leak, trying to eliminate them would be hard IMO.

Loricate answered 17/5, 2011 at 1:24 Comment(4)
I agree that it is probably nothing to worry about, but I like my logs to be clean. I have posted this as Issue 630: code.google.com/p/google-guice/issues/detail?id=630Impressionism
Re-deploying a webapp is a real use-case, and restarting all the webapps (the JVM) only for one of them can be a real operational pain.Propylite
"thread is supposed to be shared in one JVM, and Guice doesn't create another when the app is deployed again": How it can be? This means not only objects (and their classes) still remain defined in heap memory (and permgen too) with stopped undeploied context, but it means also Guice uses objects defined with classes that it can't see, since they are from another classloader.Kinky
"A common tactic is that you do hot-deploys during development [...] Then, in production you do a cold deploy on every deploy" Maybe this could have been true prior to tomcat 7, which carries parallel deployment: with this latter feature, one would like to use it for avoiding downtimes, if not balancing with other tomcat instances. So one could take care of memory leaksFolium
F
5

According to the Guice issue 630 it should be fixed in the next Guice version (as of 11/2011), i.e. when the Guava dependency is upgraded to r10+.

It seems that the fix is still not in, according to Guice issue 288.

Fbi answered 20/12, 2011 at 10:8 Comment(0)
L
3

If you are getting this when you shutdown the webapp, I wouldn't worry too much. This type of resource leak on app. shutdown is common. They do become a problem when you frequently do hot deploys (i.e. un-deploy many times without killing the JVM), but they won't be problematic when a cold deploy is done (un-deploy/deploy is done while killing the JVM before re-deploy).

A common tactic is that you do hot-deploys during development (as they are typically faster than cold-deploys), and only do a cold deploy when the resource leak starts to affect your performance. Then, in production you do a cold deploy on every deploy. Given the number of code/libraries that has this type of leak, trying to eliminate them would be hard IMO.

Loricate answered 17/5, 2011 at 1:24 Comment(4)
I agree that it is probably nothing to worry about, but I like my logs to be clean. I have posted this as Issue 630: code.google.com/p/google-guice/issues/detail?id=630Impressionism
Re-deploying a webapp is a real use-case, and restarting all the webapps (the JVM) only for one of them can be a real operational pain.Propylite
"thread is supposed to be shared in one JVM, and Guice doesn't create another when the app is deployed again": How it can be? This means not only objects (and their classes) still remain defined in heap memory (and permgen too) with stopped undeploied context, but it means also Guice uses objects defined with classes that it can't see, since they are from another classloader.Kinky
"A common tactic is that you do hot-deploys during development [...] Then, in production you do a cold deploy on every deploy" Maybe this could have been true prior to tomcat 7, which carries parallel deployment: with this latter feature, one would like to use it for avoiding downtimes, if not balancing with other tomcat instances. So one could take care of memory leaksFolium
H
0

This helped me to get rid of "SEVERE" log entry for com.google.inject.internal.InjectorImpl:

injector = null;
System.gc(); 

Where injector was the result of Guice.createInjector(...modules...)

I admit, it looks like I didn't read about bad habit of calling System.gc(), but it totally makes sense, since Guice uses weak references internally.

P.S. Tomcat 8, Java 8, Guice 3.0

Hoarding answered 25/6, 2015 at 21:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.