Author: markt
Date: Tue Oct 19 15:08:57 2010
New Revision: 1024261
URL: http://svn.apache.org/viewvc?rev=1024261&view=rev
Log:
Back-port memory leak prevention from Tomcat 7.0.x
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/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=1024261&r1=1024260&r2=1024261&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/STATUS.txt (original)
+++ tomcat/tc6.0.x/trunk/STATUS.txt Tue Oct 19 15:08:57 2010
@@ -204,11 +204,6 @@ PATCHES PROPOSED TO BACKPORT:
timw: fixed in http://svn.apache.org/viewvc?rev=1004912&view=rev
* Backport all JRE leak prevention listener changes to tc6
- http://people.apache.org/~markt/patches/2010-10-05-leak-preotection-tc6.patch
- +1: markt, kkolinko, kfujino
- -1:
-
- Additional patch:
http://svn.apache.org/viewvc?rev=1004868&view=rev
http://svn.apache.org/viewvc?rev=1004869&view=rev
+1: kkolinko, markt, kfujino
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=1024261&r1=1024260&r2=1024261&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 Oct 19 15:08:57 2010
@@ -25,6 +25,7 @@ import java.net.URL;
import java.net.URLConnection;
import javax.imageio.ImageIO;
+import javax.security.auth.Policy;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
@@ -49,6 +50,7 @@ import org.apache.tomcat.util.res.String
* first disabling Jar URL connection caching. The workaround is to disable
this
* caching by default.
*/
+...@suppresswarnings("deprecation")
public class JreMemoryLeakPreventionListener implements LifecycleListener {
private static final Log log =
@@ -66,6 +68,19 @@ public class JreMemoryLeakPreventionList
public void setAppContextProtection(boolean appContextProtection) {
this.appContextProtection = appContextProtection;
}
+
+ /**
+ * 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;
+ }
/**
* Protect against the memory leak caused when the first call to
@@ -80,6 +95,35 @@ public class JreMemoryLeakPreventionList
this.keepAliveProtection = keepAliveProtection;
}
+ /**
+ * Protect against the memory leak caused when the first call to
+ * <code>javax.security.auth.Policy</code> is triggered by a web
+ * application. This first call populate a static variable with a
reference
+ * to the context class loader. Defaults to <code>true</code>.
+ */
+ private boolean securityPolicyProtection = true;
+ public boolean isSecurityPolicyProtection() {
+ return securityPolicyProtection;
+ }
+ public void setSecurityPolicyProtection(boolean securityPolicyProtection)
{
+ this.securityPolicyProtection = securityPolicyProtection;
+ }
+
+ /**
+ * Protect against the memory leak, when the initialization of the
+ * Java Cryptography Architecture is triggered by initializing
+ * a MessageDigest during web application deployment.
+ * This will occasionally start a Token Poller thread with the thread's
+ * context class loader equal to the web application class loader.
+ * Instead we initialize JCA early.
+ * Defaults to <code>true</code>.
+ */
+ private boolean tokenPollerProtection = true;
+ public boolean isTokenPollerProtection() { return tokenPollerProtection; }
+ public void setTokenPollerProtection(boolean tokenPollerProtection) {
+ this.tokenPollerProtection = tokenPollerProtection;
+ }
+
/**
* Protect against resources being read for JAR files and, as a
side-effect,
* the JAR file becoming locked. Note this disables caching for all
@@ -95,7 +139,9 @@ public class JreMemoryLeakPreventionList
/**
* XML parsing can pin a web application class loader in memory. This is
* particularly nasty as profilers (at least YourKit and Eclipse MAT) don't
- * identify any GC roots related to this.
+ * identify any GC roots related to this.
+ * <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6916498">
+ * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6916498</a>
*/
private boolean xmlParsingProtection = true;
public boolean isXmlParsingProtection() { return xmlParsingProtection; }
@@ -103,19 +149,6 @@ public class JreMemoryLeakPreventionList
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())) {
@@ -194,6 +227,31 @@ public class JreMemoryLeakPreventionList
}
/*
+ * Calling getPolicy retains a static reference to the context
class
+ * loader.
+ */
+ if (securityPolicyProtection) {
+ try {
+ Policy.getPolicy();
+ } catch(SecurityException e) {
+ // Ignore. Don't need call to getPolicy() to be successful,
+ // just need to trigger static initializer.
+ }
+ }
+
+ /*
+ * Creating a MessageDigest during web application startup
+ * initializes the Java Cryptography Architecture. Under certain
+ * conditions this starts a Token poller thread with TCCL equal
+ * to the web application class loader.
+ *
+ * Instead we initialize JCA right now.
+ */
+ if (tokenPollerProtection) {
+ java.security.Security.getProviders();
+ }
+
+ /*
* 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
@@ -237,4 +295,5 @@ public class JreMemoryLeakPreventionList
}
}
}
+
}
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=1024261&r1=1024260&r2=1024261&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/webapps/docs/config/listeners.xml (original)
+++ tomcat/tc6.0.x/trunk/webapps/docs/config/listeners.xml Tue Oct 19 15:08:57
2010
@@ -247,7 +247,7 @@ service:jmx:rmi://<hostname>:10002
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>
+ is <code>true</code>.</p>
</attribute>
<attribute name="gcDaemonProtection" required="false">
@@ -255,7 +255,7 @@ service:jmx:rmi://<hostname>:10002
<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
+ is the creation of a thread named "GC Daemon". The protection 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>
@@ -270,6 +270,28 @@ service:jmx:rmi://<hostname>:10002
trigger a memory leak on reload. Defaults to <code>true</code>.</p>
</attribute>
+ <attribute name="securityPolicyProtection" required="false">
+ <p>Enables protection so that usage of
+ <code>javax.security.auth.Policy</code> by a web application does not
+ result in a memory leak. The first access of this class will trigger
the
+ static initializer that will retain a static reference to the context
+ class loader. The protection calls the <code>getPolicy()</code> method
+ of this class to ensure that the static initializer is not triggered by
+ a web application. Defaults to <code>true</code>.</p>
+ </attribute>
+
+ <attribute name="tokenPollerProtection" required="false">
+ <p>Enables protection so that any token poller thread initialized by
+ <code>sun.security.pkcs11.SunPKCS11.initToken()</code> does not
+ result in a memory leak. The thread is started depending on various
+ conditions as part of the initialization of the Java Cryptography
+ Architecture. Without the protection this can happen during Webapp
+ deployment when the MessageDigest for generating session IDs is
+ initialized. As a result the thread has the Webapp class loader as its
+ thread context class loader. Enabling the protection initializes JCA
+ early during Tomcat startup. Defaults to <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: [email protected]
For additional commands, e-mail: [email protected]