Author: markt Date: Tue Dec 1 18:44:32 2009 New Revision: 885860 URL: http://svn.apache.org/viewvc?rev=885860&view=rev Log: More memory leak protection - this time for the GC Daemon thread.
Modified: tomcat/trunk/java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties tomcat/trunk/webapps/docs/config/listeners.xml Modified: tomcat/trunk/java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java?rev=885860&r1=885859&r2=885860&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java (original) +++ tomcat/trunk/java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java Tue Dec 1 18:44:32 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; @@ -80,7 +82,7 @@ /** * XML parsing can pin a web application class loader in memory. This is * particularly nasty as profilers (at least YourKit and Eclispe MAT) don't - * idenitfy any GC roots related to this. + * identify any GC roots related to this. */ private boolean xmlParsingProtection = true; public boolean isXmlParsingProtection() { return xmlParsingProtection; } @@ -88,6 +90,19 @@ 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; + } + @Override public void lifecycleEvent(LifecycleEvent event) { // Initialise these classes when Tomcat starts @@ -150,8 +165,36 @@ 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) { + log.error(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/trunk/java/org/apache/catalina/core/LocalStrings.properties URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties?rev=885860&r1=885859&r2=885860&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties (original) +++ tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties Tue Dec 1 18:44:32 2009 @@ -65,6 +65,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.gcDaemonFail=Failed to trigger creation of the GC Daemon thread during Tomcat start to prevent possible memory leaks. This is expected on non-Sun JVMs. jreLeakListener.jarUrlConnCacheFail=Failed to disable Jar URL connection caching by default jreLeakListener.xmlParseFail=Error whilst attempting to prevent memory leaks during XML parsing naming.wsdlFailed=Failed to find wsdl file: {0} Modified: tomcat/trunk/webapps/docs/config/listeners.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/listeners.xml?rev=885860&r1=885859&r2=885860&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/config/listeners.xml (original) +++ tomcat/trunk/webapps/docs/config/listeners.xml Tue Dec 1 18:44:32 2009 @@ -244,7 +244,17 @@ 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"> + <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"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org