Почему простаивающий поток Java показывает высокую загрузку процессора?

Я использую Wildfly 11 с JDK 8 на Amazon Linux. Я пытаюсь выяснить, почему поток, который якобы ожидает, показывает высокую загрузку процессора. Я получил 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, связанные с этим

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)

но все, что я прочитал, указывает на то, что потоки в состоянии "ОЖИДАНИЕ" не должны занимать ресурсы ЦП. Так почему я вижу этот странный результат? Я что-то напортачил по пути?

1 ответ

Вместо использования командной строки для отслеживания активности потоков, используйте визуальную виртуальную машину Java, она намного лучше и очень поможет вам.

Используют ли потоки в состоянии "ОЖИДАНИЕ" или "ОЖИДАНИЕ" ЦП?

Есть время, необходимое для входа и выхода из режима ожидания / сна. Это сравнительно небольшая стоимость, но если ее назвать достаточно нетривиально.

В случае wait() он может внезапно пробуждаться, поэтому, если вы используете его в цикле, как это идиоматично, теоретически это может сжечь немного процессора. На практике это случается редко, по моему опыту, но достаточно часто, так что если вы забудете использовать цикл, это может создать трудности для воспроизведения ошибок.

Другие вопросы по тегам