【问题标题】:High thread context switching for java web applicationjava web应用程序的高线程上下文切换
【发布时间】:2015-05-22 10:17:02
【问题描述】:

我们一直在对我们的 java Web 应用程序进行负载测试,并观察到 ​​50 个用户的 CPU 使用率很高(这似乎不切实际)。 CPU 飙升至 80% 以上。在使用 java 飞行记录 (JFR) 对其进行分析时,我们看到上下文切换率为每秒 8400 次(如 java 任务控制上的热线程选项卡中所示)。分析 jfr 中的热线程,cpu 使用率似乎分布在应用程序线程中,每个线程使用的 cpu 不到 3%。

将用户负载增加到 100、150 或 200 个用户,我们看到 cpu 飙升至 90% 以上,吞吐量(每秒事务数)保持不变(如 50 个用户负载所见),而响应时间超过了可接受的阈值(3 秒)。将用户负载减少到 20 个用户显示 CPU 使用率平均超过 55%。由于我们的应用程序不是受 CPU 限制的应用程序,因此应用程序线程正在耗尽 CPU 肯定不是真的。 Code 选项卡组下的 Hot Packages 选项卡通过显示应用程序花费的大部分时间都在执行数据库查询来确认这一点。

我们使用 glassfish 3.1.2.2 作为我们的应用服务器,其中最大线程池配置为 100。Oracle Linux Server 版本 6.4 是我们的操作系统,Linux 内核版本为 2.6.39-400.214.4.el6uek.x86_64 .我尝试执行linux命令,即“watch -n0.5 pidstat -w -I -p”和“watch -n.5 grep ctxt /proc//status”来查看操作系统级别的自愿和非自愿线程上下文切换,但他们没有不给出任何结果。

怀疑高上下文切换可能导致 cpu 飙升,您是否有指导方针来确认线程上下文切换是高 cpu 的原因,以及有哪些方法可以调整 jvm 或应用程序如果是这个原因?

谢谢!

【问题讨论】:

    标签: java linux multithreading


    【解决方案1】:

    我知道这是一个旧的,但为了谁正在处理同样的问题。
    命令:pidstat -wt 3,将为您提供线程特定上下文切换的粒度。 然后你可以对你的java进程做一个线程转储, 并搜索您看到高上下文切换的线程号。 (您可能需要将线程编号转换为十六进制,具体取决于您的线程转储输出)。 我们仍然不确定核心问题是什么,因为上下文切换最高的线程指向:

    "NioBlockingSelector.BlockPoller-1" #37 daemon prio=5 os_prio=0 tid=0x00007f2b60b1f000 nid=0x1f48 runnable [0x00007f2b40af6000]
       java.lang.Thread.State: RUNNABLE
            at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
            at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269)
            at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:93)
            at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
            - locked <0x0000000700ae6c78> (a sun.nio.ch.Util$3)
            - locked <0x0000000700ae6c68> (a java.util.Collections$UnmodifiableSet)
            - locked <0x0000000700ae6b30> (a sun.nio.ch.EPollSelectorImpl)
            at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
            at org.apache.tomcat.util.net.NioBlockingSelector$BlockPoller.run(NioBlockingSelector.java:298)
    

    这是有道理的,因为它是一个线程选择器,但不知道如何从这里继续 :)

    【讨论】:

    • 是的。由于这已经有一段时间了,我无法尝试,但从上面的描述中我无法理解它是否会有所帮助,因为所有线程的 cpu 使用率只有 3%,而且它们中的大多数都在进行上下文切换。假设这是根本原因,下一步可以做什么仍是未知数
    【解决方案2】:

    您可以使用性能计数器来计算操作中上下文切换的次数。为此,请使用应用程序性能。

    命令应该是perf stats -e cs &lt;command&gt;。这是一个例子:

    [breno@debra ~]$ sudo perf stat  -e cs ls > /dev/null
    
    Performance counter stats for 'ls':
       0    cs   (context switch)                                             
    
       0.001932855 seconds time elapsed
    
    [breno@debra ~]$ sudo perf stat  -e cs ls -R > /dev/null
    
    Performance counter stats for 'ls -R':
    
       3,130   cs (context switch)                                                        
    
       3.537120431 seconds time elapsed
    

    【讨论】:

      猜你喜欢
      • 2011-07-23
      • 2011-07-26
      • 1970-01-01
      • 1970-01-01
      • 2017-09-09
      • 2011-07-27
      • 2020-09-01
      • 2019-01-06
      相关资源
      最近更新 更多