You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2009/12/21 17:50:19 UTC

svn commit: r892879 - in /tomcat/tc6.0.x/trunk: STATUS.txt java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java webapps/docs/changelog.xml webapps/docs/config/listeners.xml

Author: markt
Date: Mon Dec 21 16:50:18 2009
New Revision: 892879

URL: http://svn.apache.org/viewvc?rev=892879&view=rev
Log:
Sync JreLeakPreventionListener with trunk

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/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=892879&r1=892878&r2=892879&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/STATUS.txt (original)
+++ tomcat/tc6.0.x/trunk/STATUS.txt Mon Dec 21 16:50:18 2009
@@ -322,8 +322,3 @@
   rjung: I added the second commit after Mark proposed and votes. It is
          a comment typo change only. Will need more time to vote on
          the whole proposal though.
-
-* Sync JreLeakPreventionListener with trunk
-  http://people.apache.org/~markt/patches/2009-12-21-JreLeakPreventionListener.patch
-  +1: markt, rjung, jim
-  -1: 

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=892879&r1=892878&r2=892879&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 Mon Dec 21 16:50:18 2009
@@ -18,6 +18,8 @@
 package org.apache.catalina.core;
 
 import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLConnection;
@@ -49,9 +51,9 @@
  */
 public class JreMemoryLeakPreventionListener implements LifecycleListener {
 
-    protected static final Log log =
+    private static final Log log =
         LogFactory.getLog(JreMemoryLeakPreventionListener.class);
-    protected static final StringManager sm =
+    private static final StringManager sm =
         StringManager.getManager(Constants.Package);
 
     /**
@@ -59,7 +61,7 @@
      * <code>sun.awt.AppContext.getAppContext()</code> is triggered by a web
      * application. Defaults to <code>true</code>.
      */
-    protected boolean appContextProtection = true;
+    private boolean appContextProtection = true;
     public boolean isAppContextProtection() { return appContextProtection; }
     public void setAppContextProtection(boolean appContextProtection) {
         this.appContextProtection = appContextProtection;
@@ -71,7 +73,7 @@
      * {@link URLConnection}s, regardless of type. Defaults to
      * <code>true</code>.
      */
-    protected boolean urlCacheProtection = true;
+    private boolean urlCacheProtection = true;
     public boolean isUrlCacheProtection() { return urlCacheProtection; }
     public void setUrlCacheProtection(boolean urlCacheProtection) {
         this.urlCacheProtection = urlCacheProtection;
@@ -82,12 +84,25 @@
      * particularly nasty as profilers (at least YourKit and Eclipse MAT) don't
      * identify any GC roots related to this. 
      */
-    protected boolean xmlParsingProtection = true;
+    private boolean xmlParsingProtection = true;
     public boolean isXmlParsingProtection() { return xmlParsingProtection; }
     public void setXmlParsingProtection(boolean xmlParsingProtection) {
         this.xmlParsingProtection = xmlParsingProtection;
     }
     
+    /**
+     * Protect against the memory leak caused when the first call to
+     * <code>sun.misc.GC.requestLatency(long)</code> is triggered by a web
+     * application. This first call will start a GC Daemon thread with the
+     * thread's context class loader configured to be the web application class
+     * loader. Defaults to <code>true</code>.
+     */
+    private boolean gcDaemonProtection = true;
+    public boolean isGcDaemonProtection() { return gcDaemonProtection; }
+    public void setGcDaemonProtection(boolean gcDaemonProtection) {
+        this.gcDaemonProtection = gcDaemonProtection;
+    }
+    
     public void lifecycleEvent(LifecycleEvent event) {
         // Initialise these classes when Tomcat starts
         if (Lifecycle.INIT_EVENT.equals(event.getType())) {
@@ -149,8 +164,42 @@
                 try {
                     factory.newDocumentBuilder();
                 } catch (ParserConfigurationException e) {
-                    log.error(sm.getString(
-                            "jreLeakListener.xmlParseFail"), e);
+                    log.error(sm.getString("jreLeakListener.xmlParseFail"), e);
+                }
+            }
+            
+            /*
+             * Several components end up calling:
+             * sun.misc.GC.requestLatency(long)
+             * 
+             * Those libraries / components known to trigger memory leaks due to
+             * eventual calls to requestLatency(long) are:
+             * - javax.management.remote.rmi.RMIConnectorServer.start()
+             */
+            if (gcDaemonProtection) {
+                try {
+                    Class<?> clazz = Class.forName("sun.misc.GC");
+                    Method method = clazz.getDeclaredMethod("requestLatency",
+                            new Class[] {long.class});
+                    method.invoke(null, Long.valueOf(3600000));
+                } catch (ClassNotFoundException e) {
+                    if (System.getProperty("java.vendor").startsWith("Sun")) {
+                        log.error(sm.getString(
+                                "jreLeakListener.gcDaemonFail"), e);
+                    } else {
+                        log.debug(sm.getString(
+                                "jreLeakListener.gcDaemonFail"), e);
+                    }
+                } catch (SecurityException e) {
+                    log.error(sm.getString("jreLeakListener.gcDaemonFail"), e);
+                } catch (NoSuchMethodException e) {
+                    log.error(sm.getString("jreLeakListener.gcDaemonFail"), e);
+                } catch (IllegalArgumentException e) {
+                    log.error(sm.getString("jreLeakListener.gcDaemonFail"), e);
+                } catch (IllegalAccessException e) {
+                    log.error(sm.getString("jreLeakListener.gcDaemonFail"), e);
+                } catch (InvocationTargetException e) {
+                    log.error(sm.getString("jreLeakListener.gcDaemonFail"), e);
                 }
             }
         }

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=892879&r1=892878&r2=892879&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml Mon Dec 21 16:50:18 2009
@@ -318,8 +318,8 @@
       <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. Also include
-        protection against locked JAR files and memory leaks triggered by
-        XML parsing. (markt)
+        protection against locked JAR files, memory leaks triggered by
+        XML parsing and the GC Daemon. (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=892879&r1=892878&r2=892879&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/webapps/docs/config/listeners.xml (original)
+++ tomcat/tc6.0.x/trunk/webapps/docs/config/listeners.xml Mon Dec 21 16:50:18 2009
@@ -247,6 +247,16 @@
         is <code>true</code></p>
       </attribute>
 
+      <attribute name="gcDaemonProtection" required="false">
+        <p>Enables protection so that calls to
+        <code>sun.misc.GC.requestLatency(long)</code> triggered by a web
+        application do not result in a memory leak. Use of RMI is likely to
+        trigger a call to this method. A side effect of enabling this protection
+        is the creation of a thread named "GC Daemon". The protection is uses
+        reflection to access internal Sun classes and may generate errors on
+        startup on non-Sun JVMs. 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



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org