Search in sources :

Example 11 with ThreadPoolExecutor

use of org.apache.tomcat.util.threads.ThreadPoolExecutor in project tomcat70 by apache.

the class TestWebappClassLoaderThreadLocalMemoryLeak method testThreadLocalLeak1.

@Test
public void testThreadLocalLeak1() throws Exception {
    Tomcat tomcat = getTomcatInstance();
    // Need to make sure we see a leak for the right reasons
    tomcat.getServer().addLifecycleListener(new JreMemoryLeakPreventionListener());
    // No file system docBase required
    Context ctx = tomcat.addContext("", null);
    Tomcat.addServlet(ctx, "leakServlet1", "org.apache.tomcat.unittest.TesterLeakingServlet1");
    ctx.addServletMapping("/leak1", "leakServlet1");
    tomcat.start();
    Executor executor = tomcat.getConnector().getProtocolHandler().getExecutor();
    ((ThreadPoolExecutor) executor).setThreadRenewalDelay(-1);
    // Configure logging filter to check leak message appears
    TesterLogValidationFilter f = TesterLogValidationFilter.add(null, "The web application [] created a ThreadLocal with key of", null, "org.apache.catalina.loader.WebappClassLoaderBase");
    // Need to force loading of all web application classes via the web
    // application class loader
    loadClass("TesterCounter", (WebappClassLoaderBase) ctx.getLoader().getClassLoader());
    loadClass("TesterLeakingServlet1", (WebappClassLoaderBase) ctx.getLoader().getClassLoader());
    // This will trigger the ThreadLocal creation
    int rc = getUrl("http://localhost:" + getPort() + "/leak1", new ByteChunk(), null);
    // Make sure request is OK
    Assert.assertEquals(HttpServletResponse.SC_OK, rc);
    // Destroy the context
    ctx.stop();
    tomcat.getHost().removeChild(ctx);
    ctx = null;
    // Make sure we have a memory leak
    String[] leaks = ((StandardHost) tomcat.getHost()).findReloadedContextMemoryLeaks();
    Assert.assertNotNull(leaks);
    Assert.assertTrue(leaks.length > 0);
    // Make sure the message was logged
    Assert.assertEquals(1, f.getMessageCount());
}
Also used : Context(org.apache.catalina.Context) Tomcat(org.apache.catalina.startup.Tomcat) Executor(java.util.concurrent.Executor) ThreadPoolExecutor(org.apache.tomcat.util.threads.ThreadPoolExecutor) TesterLogValidationFilter(org.apache.tomcat.unittest.TesterLogValidationFilter) ByteChunk(org.apache.tomcat.util.buf.ByteChunk) StandardHost(org.apache.catalina.core.StandardHost) JreMemoryLeakPreventionListener(org.apache.catalina.core.JreMemoryLeakPreventionListener) ThreadPoolExecutor(org.apache.tomcat.util.threads.ThreadPoolExecutor) TomcatBaseTest(org.apache.catalina.startup.TomcatBaseTest) Test(org.junit.Test)

Example 12 with ThreadPoolExecutor

use of org.apache.tomcat.util.threads.ThreadPoolExecutor in project tomcat70 by apache.

the class StandardThreadExecutor method startInternal.

/**
 * Start the component and implement the requirements
 * of {@link org.apache.catalina.util.LifecycleBase#startInternal()}.
 *
 * @exception LifecycleException if this component detects a fatal error
 *  that prevents this component from being used
 */
@Override
protected void startInternal() throws LifecycleException {
    taskqueue = new TaskQueue(maxQueueSize);
    TaskThreadFactory tf = new TaskThreadFactory(namePrefix, daemon, getThreadPriority());
    executor = new ThreadPoolExecutor(getMinSpareThreads(), getMaxThreads(), maxIdleTime, TimeUnit.MILLISECONDS, taskqueue, tf);
    executor.setThreadRenewalDelay(threadRenewalDelay);
    if (prestartminSpareThreads) {
        executor.prestartAllCoreThreads();
    }
    taskqueue.setParent(executor);
    setState(LifecycleState.STARTING);
}
Also used : TaskQueue(org.apache.tomcat.util.threads.TaskQueue) ThreadPoolExecutor(org.apache.tomcat.util.threads.ThreadPoolExecutor) TaskThreadFactory(org.apache.tomcat.util.threads.TaskThreadFactory)

Example 13 with ThreadPoolExecutor

use of org.apache.tomcat.util.threads.ThreadPoolExecutor in project tomcat by apache.

the class StandardThreadExecutor method startInternal.

/**
 * Start the component and implement the requirements
 * of {@link org.apache.catalina.util.LifecycleBase#startInternal()}.
 *
 * @exception LifecycleException if this component detects a fatal error
 *  that prevents this component from being used
 */
@Override
protected void startInternal() throws LifecycleException {
    taskqueue = new TaskQueue(maxQueueSize);
    TaskThreadFactory tf = new TaskThreadFactory(namePrefix, daemon, getThreadPriority());
    executor = new ThreadPoolExecutor(getMinSpareThreads(), getMaxThreads(), maxIdleTime, TimeUnit.MILLISECONDS, taskqueue, tf);
    executor.setThreadRenewalDelay(threadRenewalDelay);
    if (prestartminSpareThreads) {
        executor.prestartAllCoreThreads();
    }
    taskqueue.setParent(executor);
    setState(LifecycleState.STARTING);
}
Also used : TaskQueue(org.apache.tomcat.util.threads.TaskQueue) ThreadPoolExecutor(org.apache.tomcat.util.threads.ThreadPoolExecutor) TaskThreadFactory(org.apache.tomcat.util.threads.TaskThreadFactory)

Example 14 with ThreadPoolExecutor

use of org.apache.tomcat.util.threads.ThreadPoolExecutor in project tomcat by apache.

the class AsyncChannelGroupUtil method createAsynchronousChannelGroup.

private static AsynchronousChannelGroup createAsynchronousChannelGroup() {
    // Need to do this with the right thread context class loader else the
    // first web app to call this will trigger a leak
    ClassLoader original = Thread.currentThread().getContextClassLoader();
    try {
        Thread.currentThread().setContextClassLoader(AsyncIOThreadFactory.class.getClassLoader());
        // These are the same settings as the default
        // AsynchronousChannelGroup
        int initialSize = Runtime.getRuntime().availableProcessors();
        ExecutorService executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, Long.MAX_VALUE, TimeUnit.MILLISECONDS, new SynchronousQueue<>(), new AsyncIOThreadFactory());
        try {
            return AsynchronousChannelGroup.withCachedThreadPool(executorService, initialSize);
        } catch (IOException e) {
            // No good reason for this to happen.
            throw new IllegalStateException(sm.getString("asyncChannelGroup.createFail"));
        }
    } finally {
        Thread.currentThread().setContextClassLoader(original);
    }
}
Also used : ExecutorService(java.util.concurrent.ExecutorService) ThreadPoolExecutor(org.apache.tomcat.util.threads.ThreadPoolExecutor) IOException(java.io.IOException)

Example 15 with ThreadPoolExecutor

use of org.apache.tomcat.util.threads.ThreadPoolExecutor in project tomcat by apache.

the class WebappClassLoaderBase method clearReferencesThreads.

// thread.stop()
@SuppressWarnings("deprecation")
private void clearReferencesThreads() {
    Thread[] threads = getThreads();
    List<Thread> threadsToStop = new ArrayList<>();
    // Iterate over the set of threads
    for (Thread thread : threads) {
        if (thread != null) {
            ClassLoader ccl = thread.getContextClassLoader();
            if (ccl == this) {
                // Don't warn about this thread
                if (thread == Thread.currentThread()) {
                    continue;
                }
                final String threadName = thread.getName();
                // JVM controlled threads
                ThreadGroup tg = thread.getThreadGroup();
                if (tg != null && JVM_THREAD_GROUP_NAMES.contains(tg.getName())) {
                    // HttpClient keep-alive threads
                    if (clearReferencesHttpClientKeepAliveThread && threadName.equals("Keep-Alive-Timer")) {
                        thread.setContextClassLoader(parent);
                        log.debug(sm.getString("webappClassLoader.checkThreadsHttpClient"));
                    }
                    // Don't warn about remaining JVM controlled threads
                    continue;
                }
                // Skip threads that have already died
                if (!thread.isAlive()) {
                    continue;
                }
                // "java.util.Timer$TimerImpl" in Apache Harmony and in IBM JDK
                if (thread.getClass().getName().startsWith("java.util.Timer") && clearReferencesStopTimerThreads) {
                    clearReferencesStopTimerThread(thread);
                    continue;
                }
                if (isRequestThread(thread)) {
                    log.warn(sm.getString("webappClassLoader.stackTraceRequestThread", getContextName(), threadName, getStackTrace(thread)));
                } else {
                    log.warn(sm.getString("webappClassLoader.stackTrace", getContextName(), threadName, getStackTrace(thread)));
                }
                // configured to do so
                if (!clearReferencesStopThreads) {
                    continue;
                }
                // If the thread has been started via an executor, try
                // shutting down the executor
                boolean usingExecutor = false;
                try {
                    // Runnable wrapped by Thread
                    // "target" in Sun/Oracle JDK
                    // "runnable" in IBM JDK
                    // "action" in Apache Harmony
                    Object target = null;
                    for (String fieldName : new String[] { "target", "runnable", "action" }) {
                        try {
                            Field targetField = thread.getClass().getDeclaredField(fieldName);
                            targetField.setAccessible(true);
                            target = targetField.get(thread);
                            break;
                        } catch (NoSuchFieldException nfe) {
                            continue;
                        }
                    }
                    // internal fork.
                    if (target != null && target.getClass().getCanonicalName() != null && (target.getClass().getCanonicalName().equals("org.apache.tomcat.util.threads.ThreadPoolExecutor.Worker") || target.getClass().getCanonicalName().equals("java.util.concurrent.ThreadPoolExecutor.Worker"))) {
                        Field executorField = target.getClass().getDeclaredField("this$0");
                        executorField.setAccessible(true);
                        Object executor = executorField.get(target);
                        if (executor instanceof ThreadPoolExecutor) {
                            ((ThreadPoolExecutor) executor).shutdownNow();
                            usingExecutor = true;
                        } else if (executor instanceof java.util.concurrent.ThreadPoolExecutor) {
                            ((java.util.concurrent.ThreadPoolExecutor) executor).shutdownNow();
                            usingExecutor = true;
                        }
                    }
                } catch (SecurityException | NoSuchFieldException | IllegalArgumentException | IllegalAccessException | InaccessibleObjectException e) {
                    log.warn(sm.getString("webappClassLoader.stopThreadFail", thread.getName(), getContextName()), e);
                }
                // them here.
                if (!usingExecutor && !thread.isInterrupted()) {
                    thread.interrupt();
                }
                // Threads are expected to take a short time to stop after
                // being interrupted. Make a note of all threads that are
                // expected to stop to enable them to be checked at the end
                // of this method.
                threadsToStop.add(thread);
            }
        }
    }
    // If thread stopping is enabled, threads should have been stopped above
    // when the executor was shut down or the thread was interrupted but
    // that depends on the thread correctly handling the interrupt. Check
    // each thread and if any are still running give all threads up to a
    // total of 2 seconds to shutdown.
    int count = 0;
    for (Thread t : threadsToStop) {
        while (t.isAlive() && count < 100) {
            try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                // Quit the while loop
                break;
            }
            count++;
        }
        if (t.isAlive()) {
            // This method is deprecated and for good reason. This is
            // very risky code but is the only option at this point.
            // A *very* good reason for apps to do this clean-up
            // themselves.
            t.stop();
        }
    }
}
Also used : CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) Field(java.lang.reflect.Field) InaccessibleObjectException(java.lang.reflect.InaccessibleObjectException) URLClassLoader(java.net.URLClassLoader) InstrumentableClassLoader(org.apache.tomcat.InstrumentableClassLoader) ThreadPoolExecutor(org.apache.tomcat.util.threads.ThreadPoolExecutor)

Aggregations

ThreadPoolExecutor (org.apache.tomcat.util.threads.ThreadPoolExecutor)18 Executor (java.util.concurrent.Executor)10 TaskQueue (org.apache.tomcat.util.threads.TaskQueue)6 ScheduledThreadPoolExecutor (java.util.concurrent.ScheduledThreadPoolExecutor)4 Context (org.apache.catalina.Context)4 JreMemoryLeakPreventionListener (org.apache.catalina.core.JreMemoryLeakPreventionListener)4 StandardHost (org.apache.catalina.core.StandardHost)4 Tomcat (org.apache.catalina.startup.Tomcat)4 TomcatBaseTest (org.apache.catalina.startup.TomcatBaseTest)4 TesterLogValidationFilter (org.apache.tomcat.unittest.TesterLogValidationFilter)4 ByteChunk (org.apache.tomcat.util.buf.ByteChunk)4 TaskThreadFactory (org.apache.tomcat.util.threads.TaskThreadFactory)4 Test (org.junit.Test)4 ResizableExecutor (org.apache.tomcat.util.threads.ResizableExecutor)3 IOException (java.io.IOException)2 ExecutorService (java.util.concurrent.ExecutorService)2 Engine (org.apache.catalina.Engine)2 Service (org.apache.catalina.Service)2 Connector (org.apache.catalina.connector.Connector)2 ProtocolHandler (org.apache.coyote.ProtocolHandler)2