How to solve jvm memory overflow

The previous question talked about how to realize jvm memory overflow. Now that it has been realized, how to solve it.

 java.lang.OutOfMemoryError: GC overhead limit exceeded   

 To put it simply, java.lang.OutOfMemoryError: GC overhead limit exceededthe reason for this is that there is currently no available memory, and the memory cannot be effectively released after multiple GCs.

As we all know, the GC process of JVM will be affected by STW.

STW: Stop-The-World: It is during the execution of the garbage collection algorithmJVM内存冻结丶应用程序停顿的⼀种状态 .

  • In STW state, JAVA's所有线程都是停⽌执⾏的 -> GC线程除外

It's just that the pause is so short that it's not easy to perceive. java.lang.OutOfMemoryError: GC overhead limit exceededThis error is thrown when 98% of the pause time is spent in GC, but only less than 2% of the heap memory is recovered as a result . Plumbr gives a schematic diagram:

 Solution

1. Give a jvm parameter (do not use)

The JVM gives a parameter to avoid this error: -XX:-UseGCOverheadLimit.

However, this parameter does not solve the problem of insufficient memory, it just delays the error occurrence time and replaces it with java.lang.OutOfMemoryError: Java heap space.

2. Increase jvm memory (depending on the situation)

There is another way to be lazy: increase the heap memory. Since the heap memory is less, just increase the heap memory.

-Xms2048m -Xmx2048m

However, this method is not a panacea. Because there may be a memory leak in the program. At this time, even if you increase the heap memory, there will be a time when it will run out.

So the first two methods are just palliatives, not the root cause.

3. Fundamentally find out the code that occupies a large memory and optimize it

In fact, there is still an ultimate method, and it is a temporary solution, which is to find the place that takes up a lot of memory and optimize the code, so that this problem will not occur.

How to find the code that needs to be optimized? It is to produce jvm snapshots through heap dump, and find objects that occupy a large amount of memory by analyzing the snapshots, so as to find the code location.

Generate snapshots by setting -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heapdumpparameters, and then use tools such as VisualVM or MAT to analyze the contents of snapshots for positioning. Passing this parameter is to write all the information of the heap memory when OOM occurs to the snapshot file, that is to say, if there is sensitive information in the heap memory at this time, it may cause information leakage.

start to solve

You can use the jvisualvm tool that comes with JDK1.8 to analyze it, but I don’t think it’s very easy to use.

So I choose to use the MAT tool

Download and install the MAT tool Baidu has, not introduced here

1. Generate dump file

Configure two parameters in the local spring project startup

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heapdump

 Then use postman to access the interface bbb/bbb01 interface, and endlessly loop into the userlist without stopping the user object.

 Finally, a memory overflow error is reported.

 Stop this service. A heapdump file will be automatically generated in the project folder.

 2. Open the dump file with the MAT tool

 Open MAT and start the following 5 steps. The heapdump file is opened.

(Note that the heapdump file cannot be opened directly after downloading mat for the first time. You need to restart the computer to open the heapdump file)

3. Understand the meaning of a little word of the MAT tool

shallow retained heap heap percentage percentage      

dominator_tree dominator tree (view classes that occupy large memory, and the objects contained in the class) This is commonly used

histogram histogram (view objects that occupy a large amount of memory)

shallow heap: the size of the object itself, if it is an array or collection, it is the total size of each element.

retained heap: the size of the object itself + the size of other objects referenced.

Shallow Size (the memory size occupied by the object itself)

Retained Size (the memory size released on Heap after being GC)

with outgoing references (see why the object consumes memory, view other objects referenced by the object)

with incoming references (see who references the object)

 4. Open the page and click dominator_tree

5. Analysis

I found that the JVMneicunyichuController class takes up a lot of memory, and then clicked to find that there are a lot of User objects in the Arraylist

6. Go to the code to find

Go to the code to find why there are so many User objects in the ArrayList collection of the JVMneicunyichuController class.

After finding the collection of this class, I found that it was a while loop that added User objects to the collection.

7. Modify and optimize the code

Remove this infinite loop, then the problem of memory overflow will be solved.

Two interfaces to help with troubleshooting and analysis:

Method 1: Click on Histogram to view objects that occupy a large amount of memory.

 There are other ways, you can find out by yourself.

Guess you like

Origin blog.csdn.net/weixin_70280523/article/details/131154974