Fixed bug #51687: Improve JreMemoryLeakPreventionListener against leak caused by...
authorschultz <schultz@13f79535-47bb-0310-9956-ffa450edef68>
Tue, 20 Sep 2011 20:17:23 +0000 (20:17 +0000)
committerschultz <schultz@13f79535-47bb-0310-9956-ffa450edef68>
Tue, 20 Sep 2011 20:17:23 +0000 (20:17 +0000)
- Added (optional) protection against sun.java2d.Disposer thread pinning a WebappClassLoader into memory in the JreMemoryLeakPreventionListener.

git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1173333 13f79535-47bb-0310-9956-ffa450edef68

java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java
webapps/docs/config/listeners.xml

index 37b13e8..3223154 100644 (file)
@@ -81,6 +81,19 @@ public class JreMemoryLeakPreventionListener implements LifecycleListener {
     }
 
     /**
+     * Protect against the memory leak caused when the
+     * <code>sun.java2d.Disposer</code> class is loaded by a web application.
+     * Defaults to <code>false</code> because a new Thread is launched.
+     */
+    private boolean java2dDisposerProtection = false;
+    public boolean isJava2DDisposerProtection() {
+        return java2dDisposerProtection;
+    }
+    public void setJava2DDisposerProtection(boolean java2dDisposerProtection) {
+        this.java2dDisposerProtection = java2dDisposerProtection;
+    }
+
+    /**
      * 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
@@ -237,6 +250,18 @@ public class JreMemoryLeakPreventionListener implements LifecycleListener {
                   java.awt.Toolkit.getDefaultToolkit();
                 }
 
+                // Trigger the creation of the "Java2D Disposer" thread.
+                // See https://issues.apache.org/bugzilla/show_bug.cgi?id=51687
+                if(java2dDisposerProtection) {
+                    try {
+                        Class.forName("sun.java2d.Disposer");
+                    }
+                    catch (ClassNotFoundException cnfe) {
+                        // Ignore this case: we must be running on a
+                        // non-Sun-based JRE.
+                    }
+                }
+
                 /*
                  * Several components end up calling:
                  * sun.misc.GC.requestLatency(long)
index 1900e7b..7044eff 100644 (file)
         startup on non-Sun JVMs. The default is <code>true</code>.</p>
       </attribute>
 
+      <attribute name="java2DDisposerProtection" required="false">
+        <p>Enables protection so that loading the
+        <code>sun.java2d.Disposer</code> class by a web application does not
+        result in a memory leak.
+        Defaults to <code>false</code> because a thread is launched.</p>
+      </attribute>
+
       <attribute name="ldapPoolProtection" required="false">
         <p>Enables protection so that the PoolCleaner thread started by
         <code>com.sun.jndi.ldap.LdapPoolManager</code> does not result in a