Подтвердить что ты не робот

Высокая загрузка процессора в Java-приложении - почему?

У меня есть Java-приложение (веб-приложение), которое порой демонстрирует очень высокую загрузку процессора (почти 90%) в течение нескольких часов. Эта команда Linux TOP показывает это. При перезапуске приложения проблема исчезает.

Итак, чтобы исследовать:

Я беру Thread Dump, чтобы найти, какие потоки делают. Несколько потоков находятся в состоянии 'RUNNABLE', в некоторых других состояниях. При повторном использовании Thread Dumps я вижу некоторые потоки, которые всегда присутствуют в состоянии 'RUNNABLE'. Таким образом, они кажутся виновниками.

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

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

Как мне исследовать - какая часть приложения или что-нить вызывает высокую загрузку процессора? - Любые другие идеи?

4b9b3361

Ответ 1

Если профайлер не применим в вашей настройке, вы можете попытаться определить поток, следующий за шагами в этот пост.

В принципе, есть три шага:

  • запустите top -H и получим PID потока с самым высоким ЦП.
  • преобразуйте PID в hex.
  • найдите поток с соответствующим HEX PID в дампе потока.

Ответ 2

Вы можете стать жертвой проблемы с сборкой мусора.

Когда вашему приложению требуется память, и он становится низким на том, что он сконфигурировал для использования сборщика мусора, будет работать часто, который потребляет много циклов процессора. Если он не сможет собрать что-либо, ваша память останется низкой, поэтому она будет запущена снова и снова. Когда вы повторно развертываете приложение, память очищается, и сбор мусора не будет происходить больше, чем требуется, поэтому загрузка процессора остается низкой, пока она не будет полностью заполнена.

Вы должны проверить, нет ли утечки памяти в приложении и что она хорошо сконфигурирована для памяти (проверьте параметр -Xmx, см. Что представляет собой Java-вариант -Xmx?)

Кроме того, что вы используете в качестве веб-фреймворка? JSF много полагается на сеансы и потребляет много памяти, считайте себя апатридом больше!

Ответ 3

Ваш первый подход должен заключаться в том, чтобы найти все ссылки на Thread.sleep и проверить, что:

  • Сон - это правильная вещь - вы должны использовать какой-то механизм ожидания, если это возможно - возможно, осторожное использование BlockingQueue поможет.

  • Если спать правильно, что вы делаете, вы спите в течение необходимого количества времени - это часто очень сложный вопрос для ответа.

Самая распространенная ошибка в многопоточном дизайне - это полагать, что все, что вам нужно делать, когда вы ожидаете, что что-то произойдет, - это проверить его и некоторое время спать в узком цикле. Это редко является эффективным решением - вы всегда должны пытаться wait для возникновения.

Второй наиболее распространенной проблемой является цикл без сна. Это еще хуже и немного легче отслеживать.

Ответ 4

В течение этих пиковых значений процессорного времени, как выглядит пользовательская загрузка? Вы говорите, что это веб-приложение, поэтому преступники, которые приходят на ум, являются проблемами использования памяти. Например, если вы храните много вещей в сеансе, и количество сеансов становится достаточно высоким, сервер приложений начнет обманывать. Это также случай, когда GC может ухудшить ситуацию в зависимости от используемой вами схемы. Более подробная информация о приложении и конфигурации сервера была бы полезной, указывая на большее количество идей отладки.

Ответ 5

В дампе потока вы можете найти номер строки, как показано ниже.

для основного потока, который в настоящее время работает...

"main" #1 prio=5 os_prio=0 tid=0x0000000002120800 nid=0x13f4 runnable [0x0000000001d9f000]
   java.lang.Thread.State: **RUNNABLE**
    at java.io.FileOutputStream.writeBytes(Native Method)
    at java.io.FileOutputStream.write(FileOutputStream.java:313)
    at com.rana.samples.**HighCPUUtilization.main(HighCPUUtilization.java:17)**