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-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org