我在Amazon Linux上使用带有JDK 8的Wildfly 11。我试图弄清楚为什么一个理应处于等待状态的线程显示出高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)
但我读到的所有内容都表明,处于“等待”状态的线程不应该占用CPU资源。那么为什么我会看到这个奇怪的结果呢?我是不是把事情搞砸了?
发布于 2018-09-12 08:51:24
与其使用命令行来监控线程的活动,不如使用Java visual VM,这会更好,并且会给你带来极大的帮助。
处于“等待”或“睡眠”状态的线程是否使用?
进入和退出睡眠/等待状态需要时间。这是相对较小的成本,但如果调用足够多,就不是微不足道的。
在wait()的情况下,它可能会错误地唤醒,所以如果你像惯用的那样在循环中使用它,理论上这可能会消耗相当多的CPU。在实践中,这种情况在我的经验中很少发生,但经常发生,如果你忘记使用一个循环,它就会很难重现bug。
https://stackoverflow.com/questions/52283308
复制相似问题