Я использую 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
а затем я просмотрел процессы, связанные с высокими процессами ЦП, связанные с этим
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» не должны занимать ресурсы процессора. Так почему же я вижу такой странный результат? Я что-то напортачил по пути?




Вместо того, чтобы использовать командную строку для отслеживания действий ваших потоков, используйте визуальную виртуальную машину Java, это намного лучше и очень поможет вам.
Используют ли потоки в состоянии "ОЖИДАНИЕ" или "СПЯЩИЙ" ЦП?
Есть время, необходимое для входа и выхода из состояния сна / ожидания. Это относительно небольшая стоимость, но нетривиальная, если ее достаточно.
В случае wait () он может ложно проснуться, поэтому, если вы используете его в цикле, как это идиоматично, теоретически это может сжечь довольно много ресурсов процессора. На практике, по моему опыту, такое случается редко, но достаточно часто, так что, если вы забудете использовать цикл, это может затруднить воспроизведение ошибок.
Визуальная виртуальная машина java находится в вашей папке JDK 1.8 => следуйте этому пути и выполните его: jdk1.8.x => bin => jvisualvm.exe
Мы используем Amazon Linux и имеем доступ только по SSH. Визуальные элементы - это непростой вариант, если я не понимаю, что такое оболочки.
parkозначает, что поток приостановлен и не использует ЦП. Нет НИКАКИХ ЗАПУСКАЕМЫХ потоков? Кроме того, взгляните на кучу и посмотрите, много ли перемещается сборщик мусора. Как правило, информации недостаточно, чтобы определить, в чем заключается ваша проблема.