Author: markt Date: Tue Dec 15 18:48:54 2009 New Revision: 890937 URL: http://svn.apache.org/viewvc?rev=890937&view=rev Log: Improve memory leak protection
Modified: tomcat/tc6.0.x/trunk/STATUS.txt tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/LocalStrings.properties tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml tomcat/tc6.0.x/trunk/webapps/docs/config/listeners.xml Modified: tomcat/tc6.0.x/trunk/STATUS.txt URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/STATUS.txt?rev=890937&r1=890936&r2=890937&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/STATUS.txt (original) +++ tomcat/tc6.0.x/trunk/STATUS.txt Tue Dec 15 18:48:54 2009 @@ -291,11 +291,6 @@ -1: +0: markt Combined patch needs to have 834047 removed and 881765 added -* Improvements to memory leak prevention - http://people.apache.org/~markt/patches/2009-11-10-leak-prevention.patch - +1: markt, kkolinko, jim - -1: - * Additional fix for https://issues.apache.org/bugzilla/show_bug.cgi?id=48097 1) Code cleanup: Remove use of WebappClassLoader$PrivilegedFindResource, because all findResourceInternal(String,String) calls are now already Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java?rev=890937&r1=890936&r2=890937&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java Tue Dec 15 18:48:54 2009 @@ -17,21 +17,64 @@ package org.apache.catalina.core; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; + import javax.imageio.ImageIO; import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleEvent; import org.apache.catalina.LifecycleListener; +import org.apache.juli.logging.Log; +import org.apache.juli.logging.LogFactory; +import org.apache.tomcat.util.res.StringManager; /** - * Provide a workaround for known places where the Java Runtime environment uses + * Provide a workaround for known places where the Java Runtime environment can + * cause a memory leak or lock files. + * <p> + * Memory leaks occur when JRE code uses * the context class loader to load a singleton as this will cause a memory leak * if a web application class loader happens to be the context class loader at * the time. The work-around is to initialise these singletons when Tomcat's * common class loader is the context class loader. + * <p> + * Locked files usually occur when a resource inside a JAR is accessed without + * first disabling Jar URL connection caching. The workaround is to disable this + * caching by default. */ public class JreMemoryLeakPreventionListener implements LifecycleListener { + protected static final Log log = + LogFactory.getLog(JreMemoryLeakPreventionListener.class); + protected static final StringManager sm = + StringManager.getManager(Constants.Package); + + /** + * Protect against the memory leak caused when the first call to + * <code>sun.awt.AppContext.getAppContext()</code> is triggered by a web + * application. Defaults to <code>true</code>. + */ + protected boolean appContextProtection = true; + public boolean isAppContextProtection() { return appContextProtection; } + public void setAppContextProtection(boolean appContextProtection) { + this.appContextProtection = appContextProtection; + } + + /** + * Protect against resources being read for JAR files and, as a side-effect, + * the JAR file becoming locked. Note this disables caching for all + * {...@link URLConnection}s, regardless of type. Defaults to + * <code>true</code>. + */ + protected boolean urlCacheProtection = true; + public boolean isUrlCacheProtection() { return urlCacheProtection; } + public void setUrlCacheProtection(boolean urlCacheProtection) { + this.urlCacheProtection = urlCacheProtection; + } + public void lifecycleEvent(LifecycleEvent event) { // Initialise these classes when Tomcat starts if (Lifecycle.INIT_EVENT.equals(event.getType())) { @@ -41,7 +84,6 @@ * * Those libraries / components known to trigger memory leaks due to * eventual calls to getAppContext() are: - * * - Google Web Toolkit via its use of javax.imageio * - Tomcat via its use of java.beans.Introspector.flushCaches() in * 1.6.0_15 onwards @@ -51,8 +93,37 @@ // Trigger a call to sun.awt.AppContext.getAppContext(). This will // pin the common class loader in memory but that shouldn't be an // issue. - ImageIO.getCacheDirectory(); + if (appContextProtection) { + ImageIO.getCacheDirectory(); + } + + /* + * Several components end up opening JarURLConnections without first + * disabling caching. This effectively locks the file. Whilst more + * noticeable and harder to ignore on Windows, it affects all + * operating systems. + * + * Those libraries/components known to trigger this issue include: + * - log4j versions 1.2.15 and earlier + * - javax.xml.bind.JAXBContext.newInstance() + */ + // Set the default URL caching policy to not to cache + if (urlCacheProtection) { + try { + // Doesn't matter that this JAR doesn't exist - just as long as + // the URL is well-formed + URL url = new URL("jar:file://dummy.jar!/"); + URLConnection uConn = url.openConnection(); + uConn.setDefaultUseCaches(false); + } catch (MalformedURLException e) { + log.error(sm.getString( + "jreLeakListener.jarUrlConnCacheFail"), e); + } catch (IOException e) { + log.error(sm.getString( + "jreLeakListener.jarUrlConnCacheFail"), e); + } + } } } Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/LocalStrings.properties URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/LocalStrings.properties?rev=890937&r1=890936&r2=890937&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/LocalStrings.properties (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/LocalStrings.properties Tue Dec 15 18:48:54 2009 @@ -59,6 +59,7 @@ httpHostMapper.container=This container is not a StandardHost interceptorValve.alreadyStarted=InterceptorValve has already been started interceptorValve.notStarted=InterceptorValve has not yet been started +jreLeakListener.jarUrlConnCacheFail=Failed to disable Jar URL connection caching by default naming.wsdlFailed=Failed to find wsdl file: {0} naming.bindFailed=Failed to bind object: {0} naming.jmxRegistrationFailed=Failed to register in JMX: {0} Modified: tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml?rev=890937&r1=890936&r2=890937&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml (original) +++ tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml Tue Dec 15 18:48:54 2009 @@ -259,7 +259,8 @@ </fix> <fix> Provide a new listener to protect against a memory leak caused by a - change in the Sun JRE from version 1.6.0_15 onwards. (markt) + change in the Sun JRE from version 1.6.0_15 onwards. Also include + protection against locked JAR files. (markt) </fix> <fix> Don't swallow exceptions in ApplicationContextFacade.doPrivileged() Modified: tomcat/tc6.0.x/trunk/webapps/docs/config/listeners.xml URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/webapps/docs/config/listeners.xml?rev=890937&r1=890936&r2=890937&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/webapps/docs/config/listeners.xml (original) +++ tomcat/tc6.0.x/trunk/webapps/docs/config/listeners.xml Tue Dec 15 18:48:54 2009 @@ -227,19 +227,36 @@ leak if a web application class loader happens to be the context class loader at the time. The work-around is to initialise these singletons when this listener starts as Tomcat's common class loader is the context class - loader at that time.</p> + loader at that time. It also provides work-arounds for known issues that + can result in locked JAR files.</p> - <p>Currently the <strong>JRE Memory Leak Prevention Listener</strong> - provides work-arounds for the following:</p> - <ul> - <li><code>sun.awt.AppContext.getAppContext()</code></li> - </ul> - <p>This listener must only be nested within <a href="server.html">Server</a> elements.</p> - <p>No additional attributes are supported by the <strong>JRE Memory Leak - Prevention Listener</strong>.</p> + <p>The following additional attributes are supported by the <strong>JRE + Memory Leak Prevention Listener</strong>:</p> + + <attributes> + + <attribute name="appContextProtection" required="false"> + <p>Enables protection so that calls to + <code>sun.awt.AppContext.getAppContext()</code> triggered by a web + application do not result in a memory leak. Note that a call to this + method will be triggered as part of the web application stop process so + it is strongly recommended that this protection is enabled. The default + is <code>true</code></p> + </attribute> + + <attribute name="urlCacheProtection" required="false"> + <p>Enables protection so that reading resources from JAR files using + <code>java.net.URLConnection</code>s does not result in the JAR file + being locked. Note that enabling this protection disables caching by + default for all resources obtained via + <code>java.net.URLConnection</code>s. Caching may be re-enabled on a + case by case basis as required. Defaults to <code>true</code>.</p> + </attribute> + + </attributes> </subsection> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org