java - 高 CPU,可能是由于上下文切换?

标签 java multithreading

我们的一台服务器的应用程序的 CPU 负载非常高。我们查看了各种统计数据,但无法找到问题的根源。

目前的一个理论是涉及的线程太多,我们应该尽量减少并发执行的线程数。只有一个主线程池,有 3000 个线程,和一个与之一起工作的 WorkManager(这是 Java EE - Glassfish)。在任何给定时刻,大约有 620 个独立的网络 IO 操作需要并行执行(使用 java.NIO 也不是一个选项)。此外,大约有 100 个不涉及 IO 的操作也是并行执行的。

这种结构效率不高,我们想看看它是否真的造成了损害,或者仅仅是一种不好的做法。原因是这个系统中的任何更改都非常昂贵(就工时而言),因此我们需要一些问题的证据。

现在我们想知道线程的上下文切换是否是原因,因为线程的数量远远超过所需的并发操作。查看日志,我们发现在给定的一秒内平均有 14 个不同的线程在执行。如果我们考虑到两个 CPU 的存在(见下文),那么每个 CPU 有 7 个线程。这听起来并不过分,但我们想验证这一点。

那么 - 我们能否排除上下文切换或线程过多的问题?

一般细节:

  1. Java 1.5(是的,它很旧),在 CentOS 5 上运行,64 位,Linux 内核 2.6.18-128.el5
  2. 机器上只有一个 Java 进程,没有别的。
  3. 两个 CPU,在 VMware 下。
  4. 8GB 内存
  5. 我们没有在机器上运行分析器的选项。
  6. 我们没有升级 Java 或操作系统的选项。

更新 如下所示,我们在具有各种负载的测试服务器上进行了平均负载(使用正常运行时间)和 CPU(使用 vmstat 1 120)的捕获。我们在每次负载变化及其测量之间等待 15 分钟,以确保系统在新负载附近稳定下来并更新平均负载数:

50% 的生产服务器工作负载:http://pastebin.com/GE2kGLkk

34% 的生产服务器工作负载:http://pastebin.com/V2PWq8CG

25% 的生产服务器工作负载:http://pastebin.com/0pxxK0Fu

CPU 使用率似乎随着负载的降低而降低,但幅度并不大(从 50% 变为 25% 并不是真正的 CPU 使用率降低 50%)。平均负载似乎与工作量无关。

还有一个问题:假设我们的测试服务器也是一个虚拟机,它的 CPU 测量值是否会受到同一主机上运行的其他虚拟机的影响(使上述测量值无用)?

更新 2 分三部分附加线程的快照(pastebin 限制)

第 1 部分:http://pastebin.com/DvNzkB5z

第 2 部分:http://pastebin.com/72sC00rc

第 3 部分:http://pastebin.com/YTG9hgF5

最佳答案

在我看来,问题是 100 个 CPU 绑定(bind)线程比其他任何问题都多。 3000 个线程池基本上是转移注意力,因为空闲线程不会消耗太多东西。 I/O 线程可能“大部分”时间都在 hibernate ,因为 I/O 是根据计算机操作在地质时间尺度上测量的。

您没有提到这 100 个 CPU 线程在做什么,或者它们持续了多长时间,但是如果您想减慢计算机的速度,那么“运行直到时间片说停止”的 100 个线程肯定会做到这一点。因为你有 100 个“随时准备运行”,所以机器将在调度程序允许的情况下尽可能快地进行上下文切换。空闲时间几乎为零。上下文切换会产生影响,因为您经常这样做。由于 CPU 线程(可能)消耗了大部分 CPU 时间,因此您的 I/O“绑定(bind)”线程将在运行队列中等待的时间比等待 I/O 的时间长。因此,更多的进程在等待(I/O 进程更频繁地退出,因为它们很快遇到 I/O 障碍,这使进程空闲下来等待下一个进程)。

毫无疑问,这里和那里都有调整以提高效率,但 100 个 CPU 线程就是 100 个 CPU 线程。在那里你无能为力。

关于java - 高 CPU,可能是由于上下文切换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9535135/

相关文章:

java - jackson 序列化奇怪的输出

java - JTable 的行过滤器

c# - "AsyncFuture<T>"还是什么? Future<T> 在后台线程中获得——它是一种模式吗?

c++ - 停止所有 C++ 线程

java - 如何在不依赖 Pivotal GemFire 缓存的情况下启动 Spring Boot 应用程序

java - useSystemProperties() 不适用于 Apache HttpClientBuilder.create() 版本 4.5.6

java - 如何多次实例化 Swing 组件的 Java 类

java - 平衡多个队列

c++ - 线程常量错误 C++

c++ - 共享内存中的std::mutex无法正常工作