我无法弄清楚为什么有几种类型的线程" ajp-nio-8009-exec-XX"得到阻止。典型的线程转储堆栈跟踪如下所示:
at sun.misc.Unsafe.park(Native Method)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
首先,我的应用程序未经过调整并具有基本配置。例如:ajp-nio连接器的server.xml配置如下所示:
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
我们在单个tomcat实例中运行多个webapps,并且正在进行多次重新部署。经过一段时间后,其中一个webapp突然开始降低其性能。 (任何其他运行的webapps绝对没有任何活动!但我仍然无法停止/删除它们。)
我附加了两个线程转储。在那,Thread_dump_1我们可以看到&#34; ajp-nio-8009-exec-XX&#34; (XX = 1,10,11,13,14,19,20,6,7,9)正在等待获得一定的锁定。
在下一个转储(Thread_dump_2)中,我们可以看到,通过获取锁定已经进行了编号为11的线程。实际上,thread_dump_1和Thread_dump_2之间的时差必须超过2-3分钟。我无法弄清楚发生了什么?我已经阅读了很多博客/答案等,但无法弄清楚我的案例中发生了什么。我只需要一个指针,我应该如何进一步调试这个问题?应该注意什么,以及我应该关注的领域是什么。从MAT我可以看到,有类加载器泄漏。
线程转储文件:
进一步的细节:我们使用了Log4j(用于存储日志到mysql),以及一个进行网络调用的自定义库(这很费时)。
更新:从GC日志中我看到,有很多GC活动正在进行,堆大小达到最大大小,GC后释放的内存不多。 Metaspace虽然没有变得充实......
答案 0 :(得分:1)
ajp-nio-8009-exec-XX
是线程池的工作线程。他们不是在等待锁定,而是等待Condition对象。这些IDLE线程只是等待任务队列中的新任务可用。这是正常情况 - 没有什么可担心的。