Нагрузка на процессор java

Какой Java поток нагружает мой процессор

Что Вы делаете, когда Ваше Java приложение потребляет 100% ЦП? Оказывается Вы легко можете найти проблемные потоки, используя встроенные Unix и JDK утилиты. Никакие инструменты профилирования не потребуются.
С целью тестирования мы будем использовать простую программу:

Как вы видите, в данном куске кода запускается 2 потока. Idle не потребляет ресурсы ЦП(
запомните, спящие потоки потребляют память, но не процессор), в то время как Busy сильно нагружает ЦП, выполняя парсинг регулярных выражений, и другие сложные процессы.
Как мы можем быстро найти проблемный кусок кода нашей программы? Во-первых мы будем использовать ‘top’, чтобы найти Id процесса(PID) java приложения. Это весьма просто:

Мы увидим первую строку вывода ‘top’, содержащую слово «java»:

Первая колонка это PID. К сожалению, оказалось, что ‘top’ использует ANSI escape codes for colors. К счастью, я нашел perl скрипт, чтобы удалить лишние символы и наконец-то извлечь PID.

Теперь, когда мы знаем PID процесса, мы можем использовать top -H, для поиска проблемных Linux потоков. Ключ -H отображает список всех потоков, и теперь колонка PID это ID потока:

Итого мы имеем ID процесса JVM и ID потока Linux. А теперь самое интересное: если вы посмотрите на вывод jstack (доступен в JDK), каждый поток имеет NID, который написан после имени.

Параметр nid=0x6552 это Hex представление ID потока:

Теперь объединим всё в один скрипт:

Последняя строка запускает jstack с определённым PID и выводит поток с совпадающим NID. Тот самый поток и будет являться проблемным.


java: cpu 100% of usage. what optimization tricks can be done? [closed]

My java program takes 30-70% of CPU usage and 3% of Memory (I use TOP linux function). I run a 32bits version of java.

Is there a way to make it faster ? Some optimization to un the java software ? (I don’t have the source code, so no source code optimization is possible).

Installing a 64bits of java would help ? some other optimization tricks ?

5 Answers 5

Trending sort is based off of the default sorting method — by highest score — but it boosts votes that have happened recently, helping to surface more up-to-date answers.

It falls back to sorting by highest score if no posts are trending.

Switch to Trending sort

Hard to tell based on your description, but here are few tips:

JVM options. Frequently running GC may cause excessive CPU usage.

Using top and jstack you can easily discover which Java threads are consuming most of the CPU.

Finally plug in some Java profiler (they don’t require sources) and examine results.

However wants you discover which threads/methods (stack traces and profiling will help you) consume the CPU, you cannot do anything more without the source code and ability to tweak it.

64bit java will definitely increase the memory usage, but you have no guarantee of lowering CPU usage. Your best bet is to contact the software vendor and send them your specs saying what’s the problem. In the meantime you can invest in better hardware.

Optimizing CPU usage without being able to interfere with the source code is a tough one.

As Jörg mentioned in his comment: «Optimization need understanding.» On the current level of understanding (i.e. no source code, no plain description of the purpose of the program), your choices are down to:

  • Check the JVM memory settings (perhaps the Java GC is the culprit)
  • Use another, better program,
  • Buy better hardware

Given that you do not have source code with you and your normal run takes at max 70% CPU, there is no way to make your program consume 100% CPU. Unless your program depends on some external complex input that you can tweak.

But it seems you goal is running your program faster, which is not possible if it was written badly or without optimisation in mind.

Again, a better CPU may run it faster but that is not «running as optimal».

The fact that it consumes only 3% memory and 30-70% CPU indicates that the program is slow in whatever it does. Since it is not consuming too much memory and too much CPU, it is slow.


High CPU Utilization in java application — why?

I have a Java Application (web-based) that at times shows very high CPU Utilization (almost 90%) for several hours. Linux TOP command shows this. On application restart, the problem goes away.

So to investigate:

I take Thread Dump to find what threads are doing. Several Threads are found in ‘RUNNABLE’ state, some in few other states. On taking repeated Thread Dumps, i do see some threads that are always present in ‘RUNNABLE’ state. So, they appear to be the culprit.

But I am unable to tell for sure, which Thread is hogging the CPU or has gone into a infinite loop (thereby causing high CPU util).

Logs don’t necessarily help, as the offending code may not be logging anything.

How do I investigate — What part of the application or what-thread is causing High CPU Utilization? — Any other ideas?

7 Answers 7

Trending sort is based off of the default sorting method — by highest score — but it boosts votes that have happened recently, helping to surface more up-to-date answers.

It falls back to sorting by highest score if no posts are trending.

Switch to Trending sort

If a profiler is not applicable in your setup, you may try to identify the thread following steps in this post.

Basically, there are three steps:

  1. run top -H and get PID of the thread with highest CPU.
  2. convert the PID to hex.
  3. look for thread with the matching HEX PID in your thread dump.

You may be victim of a garbage collection problem.

When your application requires memory and it’s getting low on what it’s configured to use the garbage collector will run often which consume a lot of CPU cycles. If it can’t collect anything your memory will stay low so it will be run again and again. When you redeploy your application the memory is cleared and the garbage collection won’t happen more than required so the CPU utilization stays low until it’s full again.

You should check that there is no possible memory leak in your application and that it’s well configured for memory (check the -Xmx parameter, see What does Java option -Xmx stand for?)

Also, what are you using as web framework? JSF relies a lot on sessions and consumes a lot of memory, consider being stateless at most!

In the thread dump you can find the Line Number as below.

for the main thread which is currently running.

During these peak CPU times, what is the user load like? You say this is a web based application, so the culprits that come to mind is memory utilization issues. If you store a lot of stuff in the session, for instance, and the session count gets high enough, the app server will start thrashing about. This is also a case where the GC might make matters worse depending on the scheme you are using. More information about the app and the server configuration would be helpful in pointing towards more debugging ideas.

Flame graphs can be helpful in identifying the execution paths that are consuming the most CPU time.

In short, the following are the steps to generate flame graphs

flame-graph.svg can be opened using browsers as well, and in short, the width of the element in stack trace specifies the number of thread dumps that contain the execution flow relatively.

There are few other approaches to generating them

  • By introducing -XX:+PreserveFramePointer as the JVM options as described here
  • Using async-profiler with -XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepoints as described here

But using async-profiler without providing any options though not very accurate, can be leveraged with no changes to the running Java process with low CPU overhead to the process.

Their wiki provides details on how to leverage it. And more about flame graphs can be found here


java cpu usage monitoring

Is there a way in monitoring CPU usage using pure Java?

6 Answers 6

Trending sort is based off of the default sorting method — by highest score — but it boosts votes that have happened recently, helping to surface more up-to-date answers.

It falls back to sorting by highest score if no posts are trending.

Switch to Trending sort

There is a gem in the comments on the article which kgiannakakis linked:

JavaSysMon manages processes and reports useful system performance metrics cross-platform. You can think of it as a cross-platform version of the UNIX `top’ command, along with the ability to kill processes. It comes in the form of a single JAR file /..

-works on Windows, Mac OS X, Linux, and Solaris.

How about using jmx mbeans?

You can use jMX beans to calculate a CPU load. Note that this measures CPU load of your java program, not the overall system load. (the question didn’t specify which)

Then as your loop (assuming your application uses a loop, otherwise what’s the point in measuring CPU usage?) use this:

You need to use double precision because a long doesn’t fit in a float (though it might work 99.9999999999999999% of the time)

If the ‘something’ you’re doing takes less than approximately 1.6ms (Windows), then the returned value will not even have increased at all and you’ll perpetually measure 0% CPU erroneously.

Because getCurrentThreadCpuTime is VERY inaccurate (with delays less than 100ms), smoothing it helps a lot:


Java EE приложение загружает процессор на 100%

Имеется сервер приложений Jboss EAP 6.4.
Наше приложение иногда загружает сервер на 100%. Работа пользователей становится невозможной.

Практически всегда это происходит во время синхронизации приложения с 1С через веб сервис.
Складывается впечатление, что приложение съедает ресурсы после получения данных: получаем большой список данных, начинаем записывать его в БД — всё зависает. Но есть нестыковки. Например, иногда данных приходит мало, а проблема всё равно появляется. Иногда наоборот — данных много, но всё работает как часы.

Использовали visualvm чтобы изучить состояние сервера. Но практически безрезультатно.
Делаю snapshot, фильтрую по нашему пакету, сортирую по total time — вверху списка обычные методы получения данных из бд, которые обычно отрабатывают сравнительно быстро.
Задумывался о блокировках БД, но пока тоже кажется маловероятным.

Важный момент получение и обработка данных идет в 1 методе, а у процессора 8 ядер. То есть получается 1 поток съедает 8 ядер, что в общем-то выглядит невозможным. Если у кого-то будут идеи, что делать в этой ситуации, было бы очень здорово.. Прилагаю данные из visual vm собранные в момент загрузки ЦП на 100%

1 ответ 1

Такие симптомы могут быть из-за проблем с расходом памяти, который приводит к излишней нагрузке на GC ( Garbage collection ) — память заканчивается, запускается GC и «съедает» 100% CPU . Если при этом не удалось высвободить достаточно много памяти, то вскоре GC запустится снова. Настройте журнализацию запусков GC и мониторьте их. Возможно, что к моменту запуска синхронизации память уже «съедена» другими процессами, и оптимизировать надо их, а не синхронизацию.

Если веб-сервис — SOAP — то там высокие накладные расходы на обработку формата XML , требуется много памяти и CPU : если есть возможность, попробуйте перейти на REST/JSON . Проверьте алгоритмы обработки синхронизации, ищите возможность создавать меньше объектов. Если синхронизация получает данные по изменениям с момента предыдущей синхронизации — попробуйте запускать её чаще, чтобы снизить объём данных, передаваемых единовременно.

Поэкспериментируйте с размером доступной приложению памяти (параметр JVM Xmx ), для промышленного сервера обычно указывают не менее 2-4 Гб. Не торопитесь сразу выделять слишком много памяти, т.к. в таком случае хоть GC, скорее всего, будет запускаться реже, но время его работы может значительно увеличиться — может наступить так называемый stop the world , во время которого приложение становится практически не работоспособным. Смотрите так же память сервера — возможно, что ОЗУ закончилось и начинается сброс её содержимого на диск.

Если версия Java не самая последняя — попробуйте обновить, т.к. алгоритмы работы GC улучшаются от версии к версии. Насколько мне известно в 8-й версии были значительные улучшения. Также существует множество настроек GC .

Советы касательно настроек JVM — это уже крайний случай: в первую очередь разбирайтесь со своим ПО, т.к. в абсолютном большинстве случаев все проблемы с производительностью кроются именно в прикладном ПО, а не в JVM .