我有一个简单的 3 层 Apache 服务器设置,它将请求发送到 Tomcat 服务器,该服务器查询(MySQL)数据库以生成 HTML 结果。我发现一旦启动 Tomcat,java 进程中就有线程正在旋转进行 futex() 调用。在几十个 Web 请求之后,试图为请求提供服务的线程被捕获在同一个 futex() 循环中,并且它停止响应所有请求——它们在客户端超时。
我已经在 Tomcat 6 和 Tomcat 7 中尝试过。我已经在 Oracle 的 Java 1.7.0_45 和 OpenJDK 1.6.0 中尝试过。这个虚拟机是一个 64 位 Redhat 6 系统,我已经尝试过他们发布的 2.6.32-358.23.2 内核和他们的 2.6.32-431.3.1 内核,所有组合都在 strace 中显示这些系统调用,并最终锁定向上。
futex(an addr, FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME, 1, {a timestamp}, ffffffff)
= -1 ETIMEDOUT (Connection timed out)
futex(an addr, FUTEX_WAKE_PRIVATE, 1) = 0
JVM 使用默认内存执行此操作,或者即使我将可用内存增加到 3GB(机器上的 4GB)。我使用 GC 记录器运行,GC 打印了一些次要集合,并且在发生锁定时没有执行。这台机器创建于 2014 年 1 月,因此不处于任何“闰秒”情况。
所以我的问题是:为什么 Java 会在一个快速循环中进行所有这些 futex() 调用,即使 JVM 应该“空闲”?他们正常吗?他们应该得到超时吗?有没有已知的解决方法?
感谢您提供信息见解。