From bc416fc23d32536d94c0fe5f53db6e3879bbc3ad Mon Sep 17 00:00:00 2001 From: markt Date: Wed, 10 Aug 2011 13:22:52 +0000 Subject: [PATCH] Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=51640 Improve memory leak protection for DriverManager git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1156171 13f79535-47bb-0310-9956-ffa450edef68 --- .../core/JreMemoryLeakPreventionListener.java | 29 +++++++++++++++++++--- webapps/docs/config/listeners.xml | 8 ++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java b/java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java index e646c8f39..91d11d2d0 100644 --- a/java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java +++ b/java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java @@ -23,6 +23,7 @@ import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; +import java.sql.DriverManager; import javax.imageio.ImageIO; import javax.xml.parsers.DocumentBuilderFactory; @@ -150,8 +151,8 @@ public class JreMemoryLeakPreventionListener implements LifecycleListener { } /** - * com.sun.jndi.ldap.LdapPoolManager class spawns a thread when it - * is initialized if the system property + * com.sun.jndi.ldap.LdapPoolManager class spawns a thread when + * it is initialized if the system property * com.sun.jndi.ldap.connect.pool.timeout is greater than 0. * That thread inherits the context class loader of the current thread, so * that there may be a web application class loader leak if the web app @@ -162,7 +163,21 @@ public class JreMemoryLeakPreventionListener implements LifecycleListener { public void setLdapPoolProtection(boolean ldapPoolProtection) { this.ldapPoolProtection = ldapPoolProtection; } - + + /** + * The first access to {@link DriverManager} will trigger the loading of + * all {@link java.sql.Driver}s in the the current class loader. The web + * application level memory leak protection can take care of this in most + * cases but triggering the loading here has fewer side-effects. + */ + private boolean driverManagerProtection = true; + public boolean isDriverManagerProtection() { + return driverManagerProtection; + } + public void setDriverManagerProtection(boolean driverManagerProtection) { + this.driverManagerProtection = driverManagerProtection; + } + @Override public void lifecycleEvent(LifecycleEvent event) { // Initialise these classes when Tomcat starts @@ -178,6 +193,14 @@ public class JreMemoryLeakPreventionListener implements LifecycleListener { ClassLoader.getSystemClassLoader()); /* + * First call to this loads all drivers in the current class + * loader + */ + if (driverManagerProtection) { + DriverManager.getDrivers(); + } + + /* * Several components end up calling: * sun.awt.AppContext.getAppContext() * diff --git a/webapps/docs/config/listeners.xml b/webapps/docs/config/listeners.xml index 8b50f6147..207a5f150 100644 --- a/webapps/docs/config/listeners.xml +++ b/webapps/docs/config/listeners.xml @@ -174,6 +174,14 @@ is true.

+ +

The first use of java.sql.DriverManager will trigger the + loading of JDBNC Driver in the the current class loader. The web + application level memory leak protection can take care of this in most + cases but triggering the loading here has fewer side-effects. The + default is true

+
+

Enables protection so that calls to sun.misc.GC.requestLatency(long) triggered by a web -- 2.11.0