Deeply understand the GC overhead limit exceeded error of JVM!

There are several difficulties in java, such as the java.lang.OutOfMemoryError: Java heap space I wrote yesterday and the java.lang.OutOfMemoryError: GC overhead limit exceeded I will write today. To understand this knowledge, you need to have a deep understanding of the underlying principles and implementation mechanisms of the JVM.

So let's talk specifically about java.lang.OutOfMemoryError: GC overhead limit exceeded today!

We all know that a major advantage of the Java language is memory management, which is the garbage collection mechanism. Compared with other languages, such as C++, there is no automatic memory recovery mechanism in these languages, and programmers need to write code manually to allocate and release memory to reuse heap memory.

It is precisely because the Java language has an automatic garbage collection mechanism, so some programmers will encounter a series of unexpected OutOfMemoryErrors when they are used improperly. Regarding OutOfMemoryError, there are currently 8 kinds of errors. Let's fix them one by one!

java.lang.OutOfMemoryError: GC overhead limit exceeded The reason this happens is that the program basically uses up all available memory, and the GC can't clean it up.

A more accurate statement should be: the proportion of time to perform garbage collection is too large, and the amount of effective computation is too small. By default, if the GC takes more than 98% of the time and the memory reclaimed by the GC is less than 2%, the JVM will throw this error.

Deeply understand the GC overhead limit exceeded error of JVM!

The java.lang.OutOfMemoryError: GC overhead limit exceeded error is only thrown in extreme cases where less than 2% of the GC has been recycled for multiple consecutive times. What happens if the GC overhead limit error is not thrown? That is, the memory cleaned up by the GC will fill up again soon, forcing the GC to execute again. This forms a vicious circle, the CPU usage has always been 100%, but GC has no results. System users will see that the system is stuck. It used to only take a few milliseconds, but now it takes several minutes to complete.

Let's look at an example of a "GC overhead limit exceeded" error:

Deeply understand the GC overhead limit exceeded error of JVM!

In order to see the effect faster, we can set the parameters of the JVM:

Deeply understand the GC overhead limit exceeded error of JVM!

It should be noted that different GC algorithms. The error messages generated are also different, and some may generate java.lang.OutOfMemoryError: Java heap space error.

Regarding specific GC algorithms, I will give you a list of Java 8 GC algorithms, and I will write a specific article later.

Deeply understand the GC overhead limit exceeded error of JVM!
Let's talk about the code that produces OutOfMemoryError above. The java.lang.OutOfMemoryError error message was thrown during Map rehash. If you use other garbage collection algorithms, such as -XX:+UseConcMarkSweepGC, or -XX:+UseG1GC, the error will be caught by the default exception handler, but there is no stacktrace information, because there is no way to fill the stacktrace information when creating an Exception.

For another example, some manufacturers' JVM is in Win7x64, Java8 environment configuration is as follows UseG1GC:

Deeply understand the GC overhead limit exceeded error of JVM!

The resulting error message is:

Deeply understand the GC overhead limit exceeded error of JVM!

The above real cases show that under resource constraints, it is impossible to accurately predict which specific reasons the program will die. Therefore, in the face of such errors, a specific error processing sequence cannot be tied.

Some people configured the following startup parameters when solving the "java.lang.OutOfMemoryError: GC overhead limit exceeded" error:

I tell you, this is a completely wrong approach. Because this use of UseGCOverheadLimit cannot really solve the problem, it can only postpone the occurrence of out of memory errors a bit, and other processing must be done at the end. Specifying this option will cover up the original java.lang.OutOfMemoryError: GC overhead limit exceeded error and turn it into a more common java.lang.OutOfMemoryError: Java heap space error message.

Sometimes the GC overhead limit error is triggered because the heap memory allocated to the JVM is insufficient. In this case, you only need to increase the heap memory size.

In most cases, increasing the heap memory does not solve the problem. For example, there is a memory leak in the program, and increasing the heap memory can only delay the time of java.lang.OutOfMemoryError: Java heap space error.

Therefore, if you want to solve the problem fundamentally, you need to investigate the code related to memory allocation. Simply put, two things need to be clarified:

  • Which type of object takes up the most memory?

  • In which part of the code are these objects allocated?

The process of solving this kind of problem and my last article "Why java.lang.OutOfMemoryError: Java heap space error occurs and how to solve it?" The process mentioned in "is the same. I won't be wordy anymore!

Guess you like

Origin blog.51cto.com/15127565/2668867