You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2017/01/09 21:50:53 UTC
svn commit: r1778061 - in /tomcat/trunk: build.xml
java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java
java/org/apache/catalina/startup/SafeForkJoinWorkerThreadFactory.java
webapps/docs/changelog.xml webapps/docs/config/listeners.xml
Author: markt
Date: Mon Jan 9 21:50:53 2017
New Revision: 1778061
URL: http://svn.apache.org/viewvc?rev=1778061&view=rev
Log:
Add memory protection for ForkJoinPool.commonPool() related memory leaks.
Added:
tomcat/trunk/java/org/apache/catalina/startup/SafeForkJoinWorkerThreadFactory.java (with props)
Modified:
tomcat/trunk/build.xml
tomcat/trunk/java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java
tomcat/trunk/webapps/docs/changelog.xml
tomcat/trunk/webapps/docs/config/listeners.xml
Modified: tomcat/trunk/build.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/build.xml?rev=1778061&r1=1778060&r2=1778061&view=diff
==============================================================================
--- tomcat/trunk/build.xml (original)
+++ tomcat/trunk/build.xml Mon Jan 9 21:50:53 2017
@@ -336,6 +336,8 @@
<include name="org/apache/catalina/startup/CatalinaProperties.*" />
<include name="org/apache/catalina/startup/ClassLoaderFactory.*" />
<include name="org/apache/catalina/startup/ClassLoaderFactory$*.*" />
+ <include name="org/apache/catalina/startup/SafeForkJoinWorkerThreadFactory.*" />
+ <include name="org/apache/catalina/startup/SafeForkJoinWorkerThreadFactory$*.*" />
<include name="org/apache/catalina/startup/Tool.*" />
<include name="org/apache/catalina/security/SecurityClassLoad.*" />
<include name="org/apache/catalina/webresources/war/**" />
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=1778061&r1=1778060&r2=1778061&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java (original)
+++ tomcat/trunk/java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java Mon Jan 9 21:50:53 2017
@@ -25,6 +25,7 @@ import java.net.URL;
import java.net.URLConnection;
import java.sql.DriverManager;
import java.util.StringTokenizer;
+import java.util.concurrent.ForkJoinPool;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
@@ -33,6 +34,7 @@ import javax.xml.parsers.ParserConfigura
import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleEvent;
import org.apache.catalina.LifecycleListener;
+import org.apache.catalina.startup.SafeForkJoinWorkerThreadFactory;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.ExceptionUtils;
@@ -63,6 +65,8 @@ public class JreMemoryLeakPreventionList
private static final StringManager sm =
StringManager.getManager(Constants.Package);
+ private static final String FORK_JOIN_POOL_THREAD_FACTORY_PROPERTY =
+ "java.util.concurrent.ForkJoinPool.common.threadFactory";
/**
* Protect against the memory leak caused when the first call to
* <code>java.awt.Toolkit.getDefaultToolkit()</code> is triggered
@@ -161,6 +165,19 @@ public class JreMemoryLeakPreventionList
}
/**
+ * {@link ForkJoinPool#commonPool()} creates a thread pool that, by default,
+ * creates threads that retain references to the thread context class
+ * loader.
+ */
+ private boolean forkJoinCommonPoolProtection = true;
+ public boolean getForkJoinCommonPoolProtection() {
+ return forkJoinCommonPoolProtection;
+ }
+ public void setForkJoinCommonPoolProtection(boolean forkJoinCommonPoolProtection) {
+ this.forkJoinCommonPoolProtection = forkJoinCommonPoolProtection;
+ }
+
+ /**
* List of comma-separated fully qualified class names to load and initialize during
* the startup of this Listener. This allows to pre-load classes that are known to
* provoke classloader leaks if they are loaded during a request processing.
@@ -336,6 +353,17 @@ public class JreMemoryLeakPreventionList
}
}
+ /*
+ * Present in Java 8 onwards
+ */
+ if (forkJoinCommonPoolProtection) {
+ // Don't override any explicitly set property
+ if (System.getProperty(FORK_JOIN_POOL_THREAD_FACTORY_PROPERTY) == null) {
+ System.setProperty(FORK_JOIN_POOL_THREAD_FACTORY_PROPERTY,
+ SafeForkJoinWorkerThreadFactory.class.getName());
+ }
+ }
+
if (classesToInitialize != null) {
StringTokenizer strTok =
new StringTokenizer(classesToInitialize, ", \r\n\t");
Added: tomcat/trunk/java/org/apache/catalina/startup/SafeForkJoinWorkerThreadFactory.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/SafeForkJoinWorkerThreadFactory.java?rev=1778061&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/startup/SafeForkJoinWorkerThreadFactory.java (added)
+++ tomcat/trunk/java/org/apache/catalina/startup/SafeForkJoinWorkerThreadFactory.java Mon Jan 9 21:50:53 2017
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.catalina.startup;
+
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory;
+import java.util.concurrent.ForkJoinWorkerThread;
+
+/**
+ * Provides a {@link ForkJoinWorkerThreadFactory} that provides {@link
+ * ForkJoinWorkerThread}s that won't trigger memory leaks due to retained
+ * references to web application class loaders.
+ * <p>
+ * Note: This class must be available on the boot strap class path for it to be
+ * visible to {@link ForkJoinPool}.
+ */
+public class SafeForkJoinWorkerThreadFactory implements ForkJoinWorkerThreadFactory {
+
+ @Override
+ public ForkJoinWorkerThread newThread(ForkJoinPool pool) {
+ return new SafeForkJoinWorkerThread(pool);
+ }
+
+
+ private static class SafeForkJoinWorkerThread extends ForkJoinWorkerThread {
+
+ protected SafeForkJoinWorkerThread(ForkJoinPool pool) {
+ super(pool);
+ setContextClassLoader(ForkJoinPool.class.getClassLoader());
+ }
+ }
+}
\ No newline at end of file
Propchange: tomcat/trunk/java/org/apache/catalina/startup/SafeForkJoinWorkerThreadFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: tomcat/trunk/webapps/docs/changelog.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1778061&r1=1778060&r2=1778061&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Mon Jan 9 21:50:53 2017
@@ -45,6 +45,15 @@
issues do not "pop up" wrt. others).
-->
<section name="Tomcat 9.0.0.M17 (markt)" rtext="in development">
+ <subsection name="Catalina">
+ <changelog>
+ <add>
+ Extend the <code>JreMemoryLeakPreventionListener</code> to provide
+ protection against <code>ForkJoinPool.commonPool()</code> related memory
+ leaks. (markt)
+ </add>
+ </changelog>
+ </subsection>
<subsection name="Coyote">
<changelog>
<fix>
Modified: tomcat/trunk/webapps/docs/config/listeners.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/listeners.xml?rev=1778061&r1=1778060&r2=1778061&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/config/listeners.xml (original)
+++ tomcat/trunk/webapps/docs/config/listeners.xml Mon Jan 9 21:50:53 2017
@@ -205,6 +205,16 @@
default is <code>true</code>.</p>
</attribute>
+ <attribute name="forkJoinCommonPoolProtection" required="false">
+ <p>Enables protection so the threads created for
+ <code>ForkJoinPool.commonPool()</code> do not result in a memory leak.
+ The protection is enabled by setting the
+ <code>java.util.concurrent.ForkJoinPool.common.threadFactory</code>
+ system property. If this property is set when Tomcat starts, Tomcat will
+ not over-ride it even if this protection is explictly enabled. The
+ default 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
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org