Profile Image
JJ

Rising pool threads in TomCat

Hi.

 

We use Adobe ColdFusion with TomCat and a recurring problem is rising pool threads. Many pool threads enter TIMED_WAIT state (parked) and never seem to release. Does anyone have any idea why that would be and how we could solve that problem?

 

Thanks.

  • adobecoldfusion

  • tomcat

  • timedwaitingstate

Please Sign In or to post your comment or answer

Profile Image

Ram Lakshmanan

Hello JJ!

 

 Majority of your threads are in TIMED_WAITING state and most of them tend to have this sort of stack trace:

 

java.lang.Thread.State: TIMED_WAITING
prio=5 blockedtime=4 blockedcount=3 waitedtime=180048694 waitedcount=3957
at java.base@11.0.9/jdk.internal.misc.Unsafe.park(Native Method)
at java.base@11.0.9/java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:234)
at java.base@11.0.9/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2123)
at java.base@11.0.9/java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1182)
at java.base@11.0.9/java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:899)
at java.base@11.0.9/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1054)
at java.base@11.0.9/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1114)
at java.base@11.0.9/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base@11.0.9/java.lang.Thread.run(Thread.java:834)

 

Strong Suspect - 'Not shutting down executor':

 

 Your application is using internal thread pool (i.e. ThreadPoolExecutor). And it looks like you are creating new Thread Pools for very frequently (may be even every request) and not shutting down the thread pool explcitly after usage. This is obvious based on the thread names in your thread dump:

 

 

 Above is the excerpt from your thread dump analsyis report generated by fastThread showing the thread names. If you see pool counter is getting incremented but thread count remains to be 1. It tells, you are creating multiple thread pools, but each thread pool  just has 1 thread in it. After usage, you are not shutting down the executor. Inorder to shutdown the executor, you need to invoke the 'Shutdown()' API. 

 

 We have solved similar problem in another application and documented our findings here. Take a look at it, you might be also running in to same issue. 

 

 NOTE: Invoking 'shutdown()' API should resolve your immediate problem. However it's not a recommended practise to create multiple thread pools with each having 1 thread in it. You may consider creating 1 thread pool with multiple threads in it.

Profile Image

JJ

Thanks for the reply.

 

The problem I have is *how* to call the shutdown method in our environment? We are using ColdFusion 2018, which is built on top of Java. We can access Java methods/objects, but I do not know how to access the Executor and call it, and when?

 

 

Profile Image

JJ

To start with I created a Java Object like this:

 

<cfset xs = createobject("java", "java.util.concurrent.ExecutorService")>

 

when I "dump" that object, I see all of its methods:

 

 

However, if I try to run shutdown() at that point I get the error:

 

"The shutdown method was not found. Either there are no methods with the specified method name and argument types or the shutdown method is overloaded with argument types that ColdFusion cannot decipher reliably. ColdFusion found 0 methods that match the provided arguments. If this is a Java object and you verified that the method exists, use the javacast function to reduce ambiguity."

 

Stuck on that.

Profile Image

Ram Lakshmanan

Hello JJ! I don't know ColdFusion. I don't know how to invoke shutdown() API. I will reach out couple of my ColdFusion contacts to see whether they can respond to it. 

Profile Image

JJ

Hi Ram, appreciate it. CF is built on top of Java. Tomcat 9 is the version we use and it has similar set up e.g. server.xml, context.xml etc.

Profile Image

Ram Lakshmanan

Hello JJ!


 Based on your application stacktrace, your application is using 'java.util.concurrent.ThreadPoolExecutor' and not 'java.util.concurrent.ExecutorService'.


'java.util.concurrent.ExecutorService' is an interface and 'java.util.concurrent.ThreadPoolExecutor' is the concerete implementation. Can you try to invoke shutdown() API on the 'java.util.concurrent.ThreadPoolExecutor'

Profile Image

JJ

Btw you also said " You may consider creating 1 thread pool with multiple threads in it."

 

How do we do that? In configuration?

Profile Image

JJ

Hi Ram. Thanks for your insights. It seems we cannot just "inject" a call to the shutdown() call. This has to be done at the "Engine" level of ColdFusion. Do you know how can we see the thread pools using a tool like jConsole using JMX/Mbeans? Is there a way do you know?

Profile Image

Ram Lakshmanan

Hello Jason!

 Here are couple of thoughts. Currently you are creating thread pool like this:

 <cfset xs = createobject("java", "java.util.concurrent.ExecutorService")>
 
 If you notice 'ExecutorService' is an interface, that's why when you invoke shutdown() API on it, we are getting this error:
 
 "The shutdown method was not found. Either there are no methods with the specified method name and argument..."
 
 Instead can you create a concrete class 'java.util.concurrent.ThreadPoolExecutor' using one of the constructor given here: https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html
 
 Then when you invoke the shutdown() API it will start to work.

Profile Image

JJ

Hi Ram, we don't create the thread(s) using our own code, we are just using Tomcat. This is an internal process.

Got something else on mind? Post Your Question

Not the answer you're looking for? Browse other questions tagged
  • adobecoldfusion

  • tomcat

  • timedwaitingstate