What causes the CPU usage of Java applications to soar?


What causes the CPU usage of Java applications to soar?


Will infinite loop while cause CPU utilization to soar?
Will frequent use of young GC lead to soaring CPU utilization?
Is CPU usage high for applications with a large number of threads?
What is the number of threads in applications with high CPU utilization?
Will threads in blocked state cause CPU utilization to soar?
Is CPU consumption us or sy in time-sharing operating system?


1. How to calculate CPU utilization?

CPU%= 1 - idleTime / sysTime * 100
Copy code
  • Idletime: CPU idle time
  • Systime: the sum of the CPU time in user mode and kernel mode

2. What is related to CPU utilization?

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

So, which operations in Java applications are more CPU intensive?

Common CPU intensive operations are listed below:

  • Frequent GC; If the traffic is high, it may lead to frequent GC or even FGC. When the amount of calls is large, the memory allocation will be so fast that the GC thread will execute continuously, which will cause the CPU to soar.
  • Serialization and deserialization. An example will be given later: when the program performs XML parsing, the number of calls increases, resulting in a full CPU.
  • Serialization and deserialization;
  • Regular expressions. I encountered a situation where regular expressions filled the CPU; The reason may be that the engine implementation used by Java regular expressions is NFA automata, which will perform backtracking during character matching. I wrote an article “hidden traps in regular expressions” to explain why in detail.
  • Thread context switching; There are many started threads whose status changes between blocked (lock wait, IO wait, etc.) and running. This can easily happen when lock contention is intense.
  • Some threads are performing non blocking operations, such as while (true) statements. If it takes a long time to calculate in the program, you can make the thread sleep.

3. Is the CPU related to processes and threads?

Now, the time-sharing operating system allocates time slices for process scheduling in a circular manner. If a process is waiting or blocking, it will not use CPU resources. Threads are called lightweight processes and share process resources. Therefore, thread scheduling is also time-sharing in the CPU. But in Java, we use JVM for thread scheduling. Therefore, generally, thread scheduling has two modes: time sharing scheduling and preemptive scheduling.


1. Will the infinite loop of while cause the CPU utilization to soar?


First, the infinite loop will call the CPU register to count, which will consume CPU resources. So, if the thread is always in an infinite loop state, will the CPU switch threads?

Unless the operating system time slice expires, the infinite loop will not give up the occupied CPU resources, and the infinite loop will continue to request the time slice from the system until the system has no free time to perform any other operations.

2. Will frequent young GC lead to soaring CPU utilization?


Young GC itself is the JVM’s operation for garbage collection. It needs to calculate memory and call registers. Therefore, frequent young GC must occupy CPU resources.

Let’s look at a real-world case. The for loop queries the data set from the database and encapsulates the new data set again. If there is not enough memory to store, the JVM reclaims data that is no longer used. Therefore, if the required storage space is large, you may receive CPU utilization alerts.

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

From time to time.

If the total number of threads is large when checking the system thread status through jstag, but the number of threads in runnable and running status is small, the CPU utilization may not be very high.

I have encountered such a situation: the number of system threads is 1000 +, of which more than 900 threads are in blocked and waiting states. This thread uses very little CPU.

However, in most cases, if the number of threads is large, the common reason is that a large number of threads are in blocked and waiting states.

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


The key factor for high CPU utilization is computing intensive operations. If there are a large number of calculations in a thread, the CPU utilization may also be high. This is why the data script task needs to run on a large-scale cluster.

5. Will threads in blocked status cause CPU utilization to soar?


The surge in CPU usage is more due to context switching or too many runnable threads. Threads that are blocked do not necessarily lead to increased CPU utilization.

6. If the CPU value us or sy in the time-sharing operating system is very high, what does this mean?

You can use the command to find the CPU values us and sy top, as shown in the following example:


Us: percentage of CPU occupied by user space. In short, we are caused by the program. By analyzing the thread stack, it is easy to find the thread in question.
SY: percentage of CPU occupied by kernel space. When sy is high, if it is caused by a program, it is basically due to thread context switching.


How to find out the cause of high CPU utilization? The analysis process is briefly described below.

If you find that the CPU utilization of the application server is very high, first check the parameters such as the number of threads, JVM and system load, and then use these parameters to prove the cause of the problem. Secondly, use jstack to print stack information and use tools to analyze thread usage (fastthread, an online thread analysis tool, is recommended).

The following is a real case:

One night, I suddenly received a message saying that the CPU utilization reached 100%. Then I used jstack to export the thread stack information.


Further check the log:

onsumer_ODC_L_nn_jmq919_1543834242875 - priority:10 - threadid:0x00007fbf7011e000 - nativeid:0x2f093 - 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)
Copy code

Now the problem is found through this log: the method used to deserialize MQ Message Entities leads to a surge in CPU utilization.

After reading three things ❤ ️

If you think this article is very helpful to you, I’d like to invite you to help me with three small things:

  1. Praise, forwarding, and your “praise and comments” are the driving force for my creation.

  2. Pay attention to the official account.Rotten pig skin“And share original knowledge from time to time.

  3. At the same time, we can look forward to the follow-up articles

What causes the CPU usage of Java applications to soar?



Recommended Today

The selector returned by ngrx store createselector performs one-step debugging of fetching logic

Test source code: import { Component } from ‘@angular/core’; import { createSelector } from ‘@ngrx/store’; export interface State { counter1: number; counter2: number; } export const selectCounter1 = (state: State) => state.counter1; export const selectCounter2 = (state: State) => state.counter2; export const selectTotal = createSelector( selectCounter1, selectCounter2, (counter1, counter2) => counter1 + counter2 ); // […]