Login With Github

What Makes The CPU Usage of Java Applications Soar?

Questions

  • Does an infinite loop of while cause the CPU usage to soar?
  • Does frequent Young GC cause the CPU usage to soar?
  • Is the CPU usage high for the applications with a large number of threads?
  • Is the number of threads large for the applications with high CPU usage?
  • Does the thread in the BLOCKED state cause the CPU usage to soar?
  • Does the CPU in the time-sharing operating system consume us or sy?

Thinking

1. How do we calculate the CPU usage?

CPU% = 1 - idleTime / sysTime * 100

  • idleTime: The time when the CPU is idle
  • sysTime: the sum of time when the CPU is in User Mode and Kernel Mode

2. What is related to the CPU usage?

It is often said that computationally intensive programs are more CPU intensive.

Then, which operations in JAVA applications are more CPU-intensive?

Here is a list about the common CPU-intensive operations:

  • Frequent GC; it may cause frequent GC or even FGC if the amount of visits is high. When the amount of calls is large, the memory allocation will be so rapid that GC thread will be executed continuously, which will cause the CPU to soar.
  • Serialization and deserialization. An example will be given later: When the program performs xml parsing, the amount of calls increases, which causes the CPU to become full.
  • Encrypt and decode;
  • Regular expression. I have encountered the situation that the regular expression made the CPU full; The reason may be that the engine implementation used by the Java regular expressions is the NFA automaton, which will perform backtracking during character matching. I have written an article "Hidden Traps in Regular Expressions" to explain the reasons in detail.
  • Thread context switching; there are many started threads, and the state of these threads changes between Blocked (lock wait, IO wait, etc.) and Running constantly. This situation can easily happen when lock contention is intense.
  • Some threads are doing non-blocking operations, such as while (true) statements. If it takes a long time to calculate in the program, you can sleep the thread.

3. Is the CPU related to processes and threads?

Now, the time-sharing operating system uses the way of round-robin to allocate time slices for process scheduling. If the process is waiting or blocking, then it will not use CPU resources. Threads are called light processes, and share process resources. So, thread scheduling is time-shared too in CPU. But in Java, we use JVM for thread scheduling. So generally, there are two modes for the scheduling of threads: time-sharing scheduling and preemptive scheduling.

Answers

1. Does an infinite loop of while cause the CPU usage to soar?

Yes.

First of all, an infinite loop will call the CPU register for counting, and this operation will occupy CPU resources. Then, will CPU switch threads if the thread is always in an infinite loop state?

An infinite loop will not give up the occupied CPU resources unless the operating system time slice expires, and the infinite loop will continue requesting for time slices to the system until the system has no free time to do anything else.

This question has been also asked in stackoverflow: why does an infinite loop of the unintended kind increase the CPU use?

https://stackoverflow.com/questions/2846165/why-does-an-infinite-loop-of-the-unintended-kind-increase-the-cpu-use

2. Does frequent Young GC cause the CPU usage to soar?

Yes.

The Young GC itself is the operation of JVM for garbage collection, which needs to compute memory and call registers. Thus, frequent Young GC must will occupy CPU resources.

Let's take a real-world case. The for loop queries the data collection from the database, and then encapsulates the new data collection again. If the memory is not large enough for the storage, JVM will recycle the data that is no longer used. Therefore, you may receive a CPU usage alarm if the storage space needed is large。

3. Is the CPU usage high for the applications with a large number of threads?

Not necessarily.

If the total number of threads is large when we check the system thread status through jstack, but the threads which are in the Runnable and Running states are not many, then the CPU usage is not necessarily high.

I have come across such a case that the number of system threads is 1000+, of which more than 900 threads are in the BLOCKED and WAITING state. The thread occupies very little CPU.

However mostly, if the number of threads is large, then the common reason is that a large number of threads are in the BLOCKED and WAITING states.

4. Is the number of threads large for the applications with high CPU usage?

Not necessarily.

The key factor for the high CPU usage is the computationally intensive operation. If there are a large number of calculations in one thread, the CPU usage may be high as well. This is also the reason why a data script task needs to run on large-scale clusters.

5. Does the thread in the BLOCKED state cause the CPU usage to soar?

Not necessarily.

The soaring of the CPU usage is more due to the context switching or the excessive runnable state threads. The threads that are in the blocked state does not necessarily cause the CPU usage to rise.

6. What does it mean if the us or sy value of CPU is high in the time-sharing operating system?

You can find the us and sy values of CPU with the top command, as in the following example:

  • us: the percentage that the user space occupies the CPU. In simple terms, high us is caused by the program. And it's easy to locate the problematic thread by analyzing the thread stack.
  • sy: the percentage that the kernel space occupies the CPU. When sy is high, if it is caused by a program, then it is basically due to the thread context switching.

Experience

How to locate the reason why the CPU usage is high? The analysis process is described briefly below.

If you find that the CPU usage of an application server is high, first, check the parameters such as the number of threads, JVM, system load, etc., and then use these parameters to prove the cause of the problem. Second, print the stack information with jstack and use tools to analyze the thread usage (fastThread, an online Thread Analysis tool, is recommanded).

The following is a real case:

One night, suddenly, I received a message that the CPU usage reached 100%. So immediately, I dumped the stack information printed with jstack and viewed the log via http://fastthread.io/

Check the specific log further:

consumer_ODC_L_nn_jmq919_1543834242875 - priority:10 - threadid:0x00007fbf7011e000 - nativeid:0x2f093 - state:RUNNABLE
stackTrace:
java.lang.Thread.State:RUNNABLE
at java.lang.Object.hashCode(Native Method)
at java.util.HashMap.hash(HashMap.java:362)
at java.util.HashMap.getEntry(HashMap.java:462)
at java.util.HashMap.containsKey(HashMap.java:449)
at com.project.order.odc.util.XmlSerializableTool.deSerializeXML(XMLSerializableTool.java:100)
at com.project.plugin.service.message.resolver.impl.OrderFinishMessageResolver.parseMessage(OrderFinishMessageResolver.java:55)
at com.project.plugin.service.message.resolver.impl.OrderFinishMessageResolver.parseMessage(OrderFinishMessageResolver.java:21)
at com.project.plugin.service.message.resolver.impl.AbstractResolver.resolve(AbstractResolver.java:28)
at com.project.plugin.service.jmq.AbstractListener.onMessage(AbstractListener.java:44)

Aha I located the problem through this log now: The method which was used to deserialize MQ message entity caused the CPU usage to soar.

0 Comment

temp