java - 为什么空闲 Java 线程显示高 CPU 使用率?

标签 java multithreading wildfly cpu-usage jstack

我在 Amazon Linux 上使用 Wildfly 11 和 JDK 8。我试图弄清楚为什么一个据称正在等待的线程显示出高 CPU 使用率。我像这样得到了我的应用程序服务器进程的 PID

[jboss@prodmachine ~]$ ps -elf | grep java
0 S jboss     8844     1  0  80   0 - 28275 wait   15:30 ?        00:00:00 /bin/sh /usr/java/wildfly/bin/standalone.sh -c standalone.xml
0 S jboss     8896  8844 99  80   0 - 7337773 futex_ 15:30 ?      08:16:14 /usr/java/default/bin/java -D[Standalone] -server -Xms64m -Xmx25600m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=1024m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman,com.newrelic -Djava.awt.headless=true -javaagent:/usr/java/wildfly/newrelic/newrelic.jar -Dorg.jboss.boot.log.file=/usr/java/wildfly/standalone/log/server.log -Dlogging.configuration=file:/usr/java/wildfly/standalone/configuration/logging.properties -jar /usr/java/wildfly/jboss-modules.jar -mp /usr/java/wildfly/modules org.jboss.as.standalone -Djboss.home.dir=/usr/java/wildfly -Djboss.server.base.dir=/usr/java/wildfly/standalone -c standalone.xml

然后我查找了与此相关的高 Cpu uprocesses
top -n 1 -H -p 8896

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                           
 9310 jboss     20   0 28.0g 4.4g  33m S 43.3 15.2   3:16.72 java                                                                               
 9207 jboss     20   0 28.0g 4.4g  33m S 13.8 15.2  42:00.05 java                                                                               
 9292 jboss     20   0 28.0g 4.4g  33m S 13.8 15.2   3:17.87 java

所以“9310”的十六进制是“0x245e”,当我用jstack进行线程转储时,这就是我要找的......
[jboss@prodmachine ~]$ /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.181-8.b13.39.39.amzn1.x86_64/bin/jstack -l 8896 > /tmp/jstack.txt

透露了这一点
"default task-86" #272 prio=5 os_prio=0 tid=0x00000000090ee800 nid=0x245e waiting on condition [0x00007f3220cee000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x0000000181c9e050> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        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 java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)

但是我读过的所有内容都表明处于“WAITING”状态的线程不应该占用 CPU 资源。那么为什么我会看到这个奇怪的结果呢?我一路上搞砸了什么吗?

最佳答案

不是使用命令行来监视线程 Activity ,而是使用 Java 可视化 VM,它要好得多,并且会极大地帮助您。

处于“WAITING”或“SLEEPING”状态的线程是否使用 CPU?

进入和退出 sleep /等待状态需要时间。如果调用足够多的话,这个成本相对较小,但不是微不足道的。

在 wait() 的情况下,它可能会虚假唤醒,因此如果您按照习惯在循环中使用它,理论上这可能会消耗相当多的 CPU。在实践中,根据我的经验,这种情况很少发生,但经常发生,如果您忘记使用循环,它可能会导致难以重现错误。

关于java - 为什么空闲 Java 线程显示高 CPU 使用率?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52283308/

相关文章:

Java 8 默认方法接口(interface)覆盖对象等于方法

android - android surfaceview在调整大小时崩溃

c# - 为什么C#中的多线程快速排序比单线程慢

C++如何运行可以随时调用的多个后台函数线程?

caching - Wildfly 刷新安全域缓存

java - Spring & Wildfly 异步请求

java - 当 RequestHandler 抛出异常时 Jetty 重试请求

java - 如何发出 Http Get 快速请求?

java - 通过 JSONObject 传递 Unicode 字符串时出错

java - 如何使用 VisualVM 对 Wildfly10 进行 CPU 配置?