似乎正在等待的线程的 CPU 利用率很高

2023-11-24

我目前正在运行一些 JMeter 测试来测试 Web 服务的性能。它使用了大量的 CPU。对于一个 JMeter 请求线程,其使用率为 10-30%(取决于请求的类型)。当我将其增加到仅 15 个线程时,CPU 利用率约为 95%。自然,我想弄清楚到底是怎么回事。我做了一个 Hprof CPU 示例(我尝试了 times 选项,但花了一个半小时才启动我的服务,并且没有消息通过)。以下是该采样的结果片段(超过 15 分钟)。



CPU SAMPLES BEGIN (total = 220846) Fri Aug 22 13:38:54 2014
rank   self  accum   count trace method
   1 14.96% 14.96%   33038 300514 java.net.PlainSocketImpl.socketAccept
   2 14.84% 29.80%   32776 301258 sun.nio.ch.EPollArrayWrapper.epollWait
   3 12.45% 42.26%   27505 313002 sun.nio.ch.EPollArrayWrapper.epollWait
   4  7.48% 49.73%   16517 300604 java.net.PlainSocketImpl.socketAccept
   5  7.18% 56.91%   15856 303203 sun.nio.ch.EPollArrayWrapper.epollWait
   6  6.18% 63.09%   13639 313001 sun.nio.ch.ServerSocketChannelImpl.accept0
   7  6.04% 69.13%   13329 304259 sun.nio.ch.EPoll.epollWait
   8  5.11% 74.23%   11275 307102 sun.nio.ch.EPollArrayWrapper.epollWait
  

以及那些顶级样本的相应堆栈:



TRACE 300514:
    java.net.PlainSocketImpl.socketAccept(:Unknown line)
    java.net.AbstractPlainSocketImpl.accept(:Unknown line)
    java.net.ServerSocket.implAccept(:Unknown line)
    java.net.ServerSocket.accept(:Unknown line)
    sun.rmi.transport.tcp.TCPTransport$AcceptLoop.executeAcceptLoop(:Unknown line)
    sun.rmi.transport.tcp.TCPTransport$AcceptLoop.run(:Unknown line)
    java.lang.Thread.run(:Unknown line)
TRACE 301258:
    sun.nio.ch.EPollArrayWrapper.epollWait(:Unknown line)
    sun.nio.ch.EPollArrayWrapper.poll(:Unknown line)
    sun.nio.ch.EPollSelectorImpl.doSelect(:Unknown line)
    sun.nio.ch.SelectorImpl.lockAndDoSelect(:Unknown line)
    sun.nio.ch.SelectorImpl.select(:Unknown line)
    org.apache.tomcat.util.net.NioBlockingSelector$BlockPoller.run(NioBlockingSelector.java:327)
TRACE 313002:
    sun.nio.ch.EPollArrayWrapper.epollWait(:Unknown line)
    sun.nio.ch.EPollArrayWrapper.poll(:Unknown line)
    sun.nio.ch.EPollSelectorImpl.doSelect(:Unknown line)
    sun.nio.ch.SelectorImpl.lockAndDoSelect(:Unknown line)
    sun.nio.ch.SelectorImpl.select(:Unknown line)
    org.apache.tomcat.util.net.NioEndpoint$Poller.run(NioEndpoint.java:1163)
    java.lang.Thread.run(:Unknown line)
TRACE 300604:
    java.net.PlainSocketImpl.socketAccept(:Unknown line)
    java.net.AbstractPlainSocketImpl.accept(:Unknown line)
    java.net.ServerSocket.implAccept(:Unknown line)
    java.net.ServerSocket.accept(:Unknown line)
    sun.management.jmxremote.LocalRMIServerSocketFactory$1.accept(:Unknown line)
    sun.rmi.transport.tcp.TCPTransport$AcceptLoop.executeAcceptLoop(:Unknown line)
    sun.rmi.transport.tcp.TCPTransport$AcceptLoop.run(:Unknown line)
    java.lang.Thread.run(:Unknown line)
TRACE 303203:
    sun.nio.ch.EPollArrayWrapper.epollWait(:Unknown line)
    sun.nio.ch.EPollArrayWrapper.poll(:Unknown line)
    sun.nio.ch.EPollSelectorImpl.doSelect(:Unknown line)
    sun.nio.ch.SelectorImpl.lockAndDoSelect(:Unknown line)
    sun.nio.ch.SelectorImpl.select(:Unknown line)
    net.spy.memcached.MemcachedConnection.handleIO(MemcachedConnection.java:217)
    net.spy.memcached.MemcachedConnection.run(MemcachedConnection.java:836)
TRACE 313001:
    sun.nio.ch.ServerSocketChannelImpl.accept0(:Unknown line)
    sun.nio.ch.ServerSocketChannelImpl.accept(:Unknown line)
    org.apache.tomcat.util.net.NioEndpoint$Acceptor.run(NioEndpoint.java:793)
    java.lang.Thread.run(:Unknown line)
TRACE 304259:
    sun.nio.ch.EPoll.epollWait(:Unknown line)
    sun.nio.ch.EPollPort$EventHandlerTask.poll(:Unknown line)
    sun.nio.ch.EPollPort$EventHandlerTask.run(:Unknown line)
    java.lang.Thread.run(:Unknown line)
TRACE 307102:
    sun.nio.ch.EPollArrayWrapper.epollWait(:Unknown line)
    sun.nio.ch.EPollArrayWrapper.poll(:Unknown line)
    sun.nio.ch.EPollSelectorImpl.doSelect(:Unknown line)
    sun.nio.ch.SelectorImpl.lockAndDoSelect(:Unknown line)
    sun.nio.ch.SelectorImpl.select(:Unknown line)
    net.spy.memcached.MemcachedConnection.handleIO(MemcachedConnection.java:217)
    net.spy.memcached.MemcachedConnection.run(MemcachedConnection.java:836)
  

正如您所看到的,超过一半的 CPU 使用率似乎来自应该等待的线程。这不应该占用CPU时间吗?

我看到了这个话题http://www.brendangregg.com/blog/2014-06-09/java-cpu-sampling-using-hprof.html这可能会让我认为这个结果具有误导性,但我的“top -H”结果显示了最大的 CPU 使用率,Zabbix 监控也是如此。所以,看起来它实际上正在消耗CPU。然而,有一个链接指向 hprof 作者的引用,其中指出:

When you have Java threads that are somehow not using the CPU, but managing to stay active, then it will appear as if those stack traces are consuming large amounts of CPU time when they aren't.

有人可以解释为什么会出现这种情况以及我可以采取哪些措施来减少这些情况下的 CPU 使用率?或者所有的CPU使用率指标实际上都是误导性的吗?如果是这样,了解我的服务中真实 CPU 利用率的更好方法是什么?


正如 Brendan Gregg 指出的您链接的博客文章,hprof 从 JVM 认为可运行的所有线程中采样。正如您在 Thread.state 的 Javadoc 中看到的,JVM 区分以下线程状态:

  • NEW:尚未启动的线程处于此状态。
  • RUNNABLE:在Java虚拟机中执行的线程处于这种状态。
  • BLOCKED:被阻塞等待监视器锁的线程处于此状态。
  • WAITING:无限期等待另一个线程执行特定操作的线程处于此状态。
  • TIMED_WAITING:等待另一个线程执行操作达指定等待时间的线程处于此状态。
  • TERMINATED:已退出的线程处于此状态。

正如我们所看到的,JVM 没有为等待 I/O 的线程提供专用状态。那是因为这样的线程实际上是被操作系统而不是JVM阻塞的。也就是说,就JVM而言,等待网络适配器的线程是可运行的。事实上,关于 RUNNABLE 状态的详细 Javadoc 写道:

可运行线程的线程状态。处于可运行状态的线程正在Java虚拟机中执行,但它可能正在等待来自操作系统的其他资源,例如处理器。

因此,hprof“cpu”采样中存在 I/O 方法并不意味着这些方法消耗了 CPU,因为它们的等待时间也被计算在内。

您可以:

  • 假设 I/O 方法不负责 CPU 消耗,并关注其他方法
  • 使用更好的分析器,考虑等待操作系统级资源
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

似乎正在等待的线程的 CPU 利用率很高 的相关文章

随机推荐

  • Azure B2C 禁用 SignUpAndSignIn 策略的注册

    我需要一些有关自定义 Azure B2C 的建议 我一直在研究基于门户的定制和身份体验框架 我的关键要求是完全控制登录体验的外观和感觉 但是 用户不能注册 因为这是由单独的业务流程处理的 我了解我无法使用简单的登录策略 因为 B2C 不提供
  • 什么是 NullPointerException,如何修复它?

    这个问题的答案是社区努力 编辑现有答案以改进这篇文章 目前不接受新的答案或互动 什么是空指针异常 java lang NullPointerException 以及是什么导致了它们 可以使用哪些方法 工具来确定原因 以便阻止异常导致程序提前
  • Python:gettext 在 Windows 上不加载翻译

    这段特定的代码在 Linux 上运行得很好 但在 Windows 上则不然 locale setlocale locale LC ALL gettext bindtextdomain exposong LOCALE PATH gettext
  • iOS,ld:找不到架构arm64的GoogleMaps框架

    我正在开发一个使用谷歌地图的应用程序 我会解释我用谷歌地图做了什么 也许你可以帮助我 我在没有 POD 的情况下使用 Google 地图框架 但在出现一些关于 Google 地图密钥的错误后 我删除了 google 地图框架参考 并使用 P
  • 动态壁纸水波纹效果

    我正在制作一个动态壁纸 其中包含触摸屏幕时的一些水波纹效果 但我有点卡住了 创建多个图像并循环它们以创建波纹动画会更好吗 或者在将位图放置在画布上之前稍微扭曲位图会更好吗 This是一个通过 OpenGL 实现的非常漂亮的波纹效果的视频 我
  • 如何获取 iframe 中 PDF 文档加载的高度

    有没有办法获取 iframe 中加载的 PDF 内容的实际高度 我在 iPAD 设备中滚动 PDF 内容时遇到问题 我可以获得正文内容的高度 使滚动成功 但仅限于 HTML 页面 this contentWindow document bo
  • Elastic Search 和“子查询”

    可以在Elastic Search中执行子查询吗 我正在查找文档列表 通常大约 5 20 个文档 对于每个文档 我想执行搜索以为其提供一些自定义字段 每个文档都是一个属性 并且 我想分析找到的每个属性的周围属性 以评估其周围属性的平均价格
  • Java 8 将 Map> 转换为 Map>

    我需要转换Map
  • Firebase 功能会减慢冷启动时间

    I read here端点旋转应该是透明的 我认为这意味着冷启动时间不应与常规执行时间不同 现在还是这样吗 我们的所有端点的冷启动时间都非常慢且无法使用 大约 16 秒 冷启动 Function execution took 16172 m
  • 无法将“System.Data.Common.DataRecordInternal”类型的对象转换为“System.Data.IDataReader”类型

    当尝试创建时thislinq 语句 我遇到了以下错误 无法转换 System Data Common DataRecordInternal 类型的对象 输入 System Data IDataReader 这就是我按照 SLaks 所做的有
  • C# - Listview 列标题高度(Windows 窗体)

    如何更改 ListView 中列标题的高度 视觉工作室 2008 Windows 窗体 这并不容易 但可以做到 基本策略是从ListView 使用 LVM GETHEADER 消息 设置NativeWindow该控件上的实例 然后侦听 HD
  • 如何从硬编码静态配置文件切换到 .properties 文件?

    我有一些代码使用一个包含大量硬编码常量的类 它看起来是这样的 class Constants public static final String name1 value1 public static final String name2
  • 对象不支持 Internet Explorer 10 (Windows 8) 中的属性或方法“transformNode”

    我遇到了一些 JavaScript 问题 这些问题似乎只出现在 Windows 8 上的 Internet Explorer 10 中 IE 7 8 和 9 都工作正常 我所做工作的基本要点是从 Web 服务获取 XML 和 XSL 然后在
  • 使用seaborn在python中绘制3列的热图

    v1 v2 yy 15 25 44 34 100 00 83 05 59 78 100 00 96 61 65 09 100 00 100 00 75 47 100 00 100 00 50 00 100 00 100 00 68 87 1
  • SharedPreferences 中保存的用户设置在应用程序重新加载之间被删除或丢失

    我的应用程序将简单的设置存储在SharedPreferences效果很好 然而 对于下载了我的应用程序的人来说 却遇到了问题 中的设置SharedPreferences在关闭和重新加载应用程序之间迷失了方向 他的手机上是否存在权限问题 导致
  • 在 Material UI 中将变量发送到 withStyles?

    我有以下内容 class StyledInput extends React Component styles color theme gt underline borderBottom 2px solid color after bord
  • winforms中的IDataErrorInfo

    IDataError 信息可以在 winforms 应用程序中正确使用吗 过去 我以通常的方式进行绑定 1 并在特定控件的 OnValidating 事件中进行验证 我想将数据验证移至域模型 以便我可以轻松地更换用户界面 并将所有逻辑都集中
  • 如何同时拥有 VSTO 功能区和上下文菜单?

    编辑 海报的答案是正确的 除了它应该读取 xmlns http schemas microsoft com office 2009 07 customui 的包含内容 作为副作用 XML 文件中定义的功能区和上下文菜单在 Office 20
  • RPC有超时机制吗?

    如果 RPC 没有超时机制 当 RPC 调用尝试调用已关闭的服务器的 RPC 方法时 如何 杀死 它 您可以使用channels实现超时模式 import time c make chan error 1 go func c lt clie
  • 似乎正在等待的线程的 CPU 利用率很高

    我目前正在运行一些 JMeter 测试来测试 Web 服务的性能 它使用了大量的 CPU 对于一个 JMeter 请求线程 其使用率为 10 30 取决于请求的类型 当我将其增加到仅 15 个线程时 CPU 利用率约为 95 自然 我想弄清