From: markt Date: Wed, 25 Nov 2009 23:56:30 +0000 (+0000) Subject: More memory leak protection. This one is particularly nasty as profilers don't appear... X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=eaab1d769391c6f8330662f74ed4e9c6a1e3ceee;p=tomcat7.0 More memory leak protection. This one is particularly nasty as profilers don't appear to show the GC root associated with the leak. git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@884341 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java b/java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java index 4554f8f28..13eac0130 100644 --- a/java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java +++ b/java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java @@ -23,6 +23,8 @@ import java.net.URL; import java.net.URLConnection; import javax.imageio.ImageIO; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleEvent; @@ -75,6 +77,17 @@ public class JreMemoryLeakPreventionListener implements LifecycleListener { this.urlCacheProtection = urlCacheProtection; } + /** + * 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. + */ + protected boolean xmlParsingProtection = true; + public boolean isXmlParsingProtection() { return xmlParsingProtection; } + public void setXmlParsingProtection(boolean xmlParsingProtection) { + this.xmlParsingProtection = xmlParsingProtection; + } + @Override public void lifecycleEvent(LifecycleEvent event) { // Initialise these classes when Tomcat starts @@ -122,7 +135,23 @@ public class JreMemoryLeakPreventionListener implements LifecycleListener { "jreLeakListener.jarUrlConnCacheFail"), e); } catch (IOException e) { log.error(sm.getString( - "jreLeakListener.jarUrlConnCacheFail"), e); + "jreLeakListener.jarUrlConnCacheFail"), e); + } + } + + /* + * Haven't got to the root of what is going on with this leak but if + * a web app is the first to make the calls below the web + * application class loader will be pinned in memory. + */ + if (xmlParsingProtection) { + DocumentBuilderFactory factory = + DocumentBuilderFactory.newInstance(); + try { + factory.newDocumentBuilder(); + } catch (ParserConfigurationException e) { + log.error(sm.getString( + "jreLeakListener.xmlParseFail"), e); } } } diff --git a/java/org/apache/catalina/core/LocalStrings.properties b/java/org/apache/catalina/core/LocalStrings.properties index 5fbad194c..f67360301 100644 --- a/java/org/apache/catalina/core/LocalStrings.properties +++ b/java/org/apache/catalina/core/LocalStrings.properties @@ -66,6 +66,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.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} naming.bindFailed=Failed to bind object: {0} naming.jmxRegistrationFailed=Failed to register in JMX: {0} diff --git a/webapps/docs/config/listeners.xml b/webapps/docs/config/listeners.xml index 9113892f2..f882a9d18 100644 --- a/webapps/docs/config/listeners.xml +++ b/webapps/docs/config/listeners.xml @@ -256,6 +256,13 @@ service:jmx:rmi://<hostname>:10002/jndi/rmi://<hostname>:10001/jmxrm case by case basis as required. Defaults to true.

+ +

Enables protection so that parsing XML files within a web application + does not result in a memopry leak. Note that memory profilers may not + display the GC root associated with this leak making it particularly + hard to diagnose. Defaults to true.

+
+