I’m using Eclipse to develop a java web app and My IT department called and said I had over 75 open oracle connections to the development Oracle Server originating from my PC. The deployed app has been using the same singleton connection bean for a year now and I haven’t had any trouble with exceeding connections there. IT even connfirmed I only had 4 open connections on the deployment server. Something is going on when I develop locally in Eclipse.
Looking at the console debug output, everything looks good on initial startup
Sep 27, 2010 9:39:08 AM org.apache.catalina.startup.Catalina start
== no ConnCache Bean instance found
== Initializing Connection Cache Data Src
== About to load the properties
== Initializing Datasource for using jdbc:oracle:thin:@hostname:port:oracle-sid
== Reading property file
== Setting InitialLimit to 3
== Properties {TimeToLiveTimeout=4, MinLimit=4, ConnectionWaitTimeout=44, MaxLimit=5, InitialLimit=3, AbandonedConnectionTimeout=281, InactivityTimeout=269}
But then I noticed the following SEVERE message in the console When Eclipse reloads the context
Sep 27, 2010 9:40:38 AM org.apache.catalina.core.StandardContext reload
INFO: Reloading this Context has started
Sep 27, 2010 9:40:38 AM org.apache.catalina.loader.WebappClassLoader clearReferencesJdbc
SEVERE: The web application [] registered the JBDC driver [oracle.jdbc.driver.OracleDriver] but failed to unregister
it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
Sep 27, 2010 9:40:38 AM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [] appears to have started a thread named [Thread-9] but has failed to stop it.
This is very likely to create a memory leak.
I’m guessing that Eclipse is recreating a connection cache everytime the it reloads the context and the old connections and cache are not getting destroyed. How can I get Eclipse to terminate the cache or close all previous connections when the context is reloaded. I can post my connectionBean class if necessary.
It appears that you are leaking memory via the unclosed connections of the previous version of the application. This is quite possible if you’ve chosen to perform automatic publishing of your web application from Eclipse to Tomcat.
Tomcat will discard the current classloader of the web application, when it attempts to perform a reload. All objects from this GC root (the classloader), that will still be held, will not be garbage collected. Due to the presence of the singleton (I’m assuming that the singleton stores a
DataSourceobject or is maintaining a pool ofConnectionobjects), theseConnectionobjects will never be treated as unreachable objects, and hence, will not be eligible for GC.In the short run, you can do the following:
ServletContextListener, and attempt to discard the singleton reference when the servlet (application) context is destroyed. This makes the singleton object unreachable, and hence eligible for GC. This is recommended, for the same is bound to occur in production, unless Tomcat is restarted.By the way, this behavior, where in singletons cause memory and hence connection leakage will occur in any application server, as long as the application is redeployed time and again without restarting the server. The only way to prevent this, is to ensure that the singleton is destroyed when the application context is destroyed.