java - 无法理解为什么 "ajp-nio-8009-exec-XX"线程在 AbstractQueuedSynchronizer$ConditionObject.await 上阻塞/time_wait

标签 java multithreading jvm

我无法弄清楚为什么几个“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" />

我们有多个 Web 应用程序在单个 tomcat 实例中运行,并且正在进行多个重新部署。一段时间后,其中一个 Web 应用程序的性能突然开始下降。 (任何其他正在运行的网络应用程序上绝对没有任何 Activity !但我仍然无法停止/删除它们。)

我附加了两个线程转储。在Thread_dump_1中,我们可以看到“ajp-nio-8009-exec-XX”(XX=1,10,11,13,14,19,20,6,7,9)正在等待获取某个锁。

在下一个转储(Thread_dump_2)中,我们可以看到编号为 11 的线程已通过获取锁进行了操作。事实上,thread_dump_1和Thread_dump_2的时间差肯定在2-3分钟以上。我不明白发生了什么?我读过很多博客/答案等,但无法弄清楚我的情况发生了什么。我只需要一个关于如何进一步调试这个问题的指示?应该注意什么,哪些方面是我应该多加关注的。从 MAT 中我可以看到,存在类加载器泄漏。

线程转储文件:

Thread_dump_1 Thread_dump_1

更多细节:我们使用了Log4j(用于将日志存储到mysql),以及一个进行网络调用的自定义库(这很耗时)。

更新:从 GC 日志中我看到,正在进行大量 GC Activity ,堆大小达到最大大小,并且 GC 后没有释放太多内存。不过元空间还没有满……

最佳答案

ajp-nio-8009-exec-XX 是线程池的工作线程。他们不是在等待锁,而是在 Condition 上等待。目的。这些空闲线程只是在等待,直到任务队列中有可用的新任务。这是正常情况 - 无需担心。

关于java - 无法理解为什么 "ajp-nio-8009-exec-XX"线程在 AbstractQueuedSynchronizer$ConditionObject.await 上阻塞/time_wait,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49174116/

相关文章:

java - Thread.interrupt 上的 IllegalThreadStateException

java - 什么更快 : instanceof or isInstance?

memory - 为什么我的垃圾收集日志显示 3.8GB 作为最大可用堆大小,而我已分配 4GB 作为最大堆大小?

java - Mac 上 Eclipse 的键盘设置

c# - 跟踪Web应用程序中单例进程的进程

java - 如何使用 Guice 的 AssistedInject?

android - 持续监控 Android 中的传感器

Java 接口(interface)合成方法生成,同时缩小返回类型

java - 如何在Eclipse中调试乐山代码

java - 使用 spark 将 POST 正文解析为 java 对象