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

Reply via email to