JVM memory leak analysis (the most complete in history)

The article is very long, it is recommended to collect it and read it slowly! Remarks: Continuously updating...

Classic books and materials necessary for entering a large factory, upgrading the structure, and getting a high salary:


Recommendation 2: General list of interview questions for 2021 spring recruits with a monthly salary of over 50,000

Get the following interview questions, the monthly salary of 2021 spring recruits is more than 50,000 (strong!) Ali, Jingdong, Meituan, Toutiao... Pick and walk sideways at will! ! !
Java basics
1: JVM interview questions (the strongest in history, continuous update, hematemesis recommendation) https://www.cnblogs.com/crazymakercircle/p/14365820.html
2: Java basic interview questions (the most complete in history, continuous update, hematemesis recommendation) https://www.cnblogs.com/crazymakercircle/p/14366081.html
3: Deadlock interview questions (the strongest in history, continuously updated) [https://www.cnblogs.com/crazymakercircle/p/14323919.html]
4: Design pattern interview questions (the most comprehensive in history, continuous update, hematemesis recommendation) https://www.cnblogs.com/crazymakercircle/p/14367101.html
5: Architecture design interview questions (the most comprehensive in history, continuous update, hematemesis recommendation) https://www.cnblogs.com/crazymakercircle/p/14367907.html
There are also 10 + interview questions that must be brushed and brushed For more..., please refer to【Crazy Maker Circle High Concurrency Catalog

Recommendation 3: Crazy Maker Circle springCloud high concurrency series

springCloud high-quality blog posts
nacos actual combat (the most complete in history) sentinel (the most complete + introductory tutorial in history)
springcloud + webflux high concurrency combat Webflux (the most complete in history)
SpringCloud gateway (the most complete in history)
There are 10 + articles will brush, brush will be of high quality Bowen For more..., please refer to【Crazy Maker Circle High Concurrency Catalog

JVM performance optimization interview questions

Common problems of JVM memory area

Is there a memory leak in Java, briefly?

Java memory allocation?

What is the structure of the Java heap?

What is Perm Gen space in the heap?

Briefly describe the changes in the memory area of ​​each version?

Talk about the role of each area?

Common problems of JVM execution subsystem

Java class loading process?

Describe the principle and mechanism of JVM loading Class files? What is a class loader?

What are the class loaders?

The class loader parent delegation model mechanism?

Frequently Asked Questions about Garbage Collection

What is GC?

Why is there a GC?

Briefly describe the Java garbage collection mechanism?

How to judge whether an object is alive?

The advantages and principles of garbage collection, and consider 2 types of recycling mechanisms?

What is the basic principle of the garbage collector?

Can the garbage collector reclaim memory immediately?

Is there any way to proactively notify the virtual machine for garbage collection?

Deep copy and shallow copy?

What will System.gc() and Runtime.gc() do?

If the object's reference is set to null, will the garbage collector immediately release the memory occupied by the object?

What is distributed garbage collection (DGC)?

How does it work?

What is the difference between a serial collector and a throughput collector?

In Java, when can an object be garbage collected? Briefly describe Minor GC and Major GC? Will garbage collection occur in the permanent generation of the JVM? What are the methods of garbage collection in Java?

Performance optimization common problems

Tell me about the performance evaluation and test indicators you understand?

What are the commonly used performance optimization methods?

What is GC tuning?

JVM tuning tool

Jconsole,jProfile,VisualVM

Jconsole: jdk comes with it, with simple functions, but it can be used when the system has a certain load. There is a very detailed tracking of the garbage collection algorithm. For details, please refer to here

JProfiler : Commercial software, need to pay. Powerful. For details, please refer to here

VisualVM : JDK comes with, powerful, similar to JProfiler. recommend.

A Preliminary Study of JVisualVM

​ VisualVM is the profile sub-project of Netbeans, which is included in JDK6.0 update 7 (no specific parameters are required when java starts, the monitoring tool is in bin/jvisualvm.exe), which can monitor threads, memory conditions, and view the CPU time of the method And the objects in the memory, the objects that have been GC, the reverse view of the allocated stack (for example, which objects are allocated by 100 String objects).

​ Under the JDK_HOME/bin (C:\Program Files\Java\jdk1.6.0_13\bin by default), there is a jvisualvm.exe file. Double-click to open it. From the UI, this software is developed based on NetBeans.

​ Can carry out remote and local monitoring. Remote monitoring needs to open jmx, which will be mentioned below.

​ Its default page is:

img

The left side is divided into local and remote. Double-click the VisualVM thread in the local, you can see the following monitoring content:

img

For specific introduction, please refer to:

http://www.ibm.com/developerworks/cn/java/j-lo-visualvm/

VisualVM can install different plug-ins according to needs. Each plug-in has a different focus. Some mainly monitor GC, some mainly monitor memory, and some monitor threads.
Insert picture description here
how to install:

1. Select "Tools"> "Plugins" from the main menu. 2. In the "Available Plugins" tab, select the "Install" checkbox of the plugin. Click "Install". 3. Complete the plug-in installation procedure step by step.

Here I take Eclipse (pid 22296) as an example. Double-click it and expand directly. The main interface shows the two major contents of system and jvm. Click on the jvm parameters and system properties at the bottom right to refer to detailed parameter information.
Insert picture description here
Because there are too many plug-ins for VisualVM, I will mainly introduce three here. I mainly use a few: monitoring, threading, Visual GC
monitoring homepage is actually, cpu, memory, class, thread charts,
Insert picture description here
there is not much difference between thread and jconsole function
Insert picture description here
Visual GC is a frequently used one. Function, you can clearly see the memory changes of the young generation and the old generation, as well as the gc frequency and gc time.
Insert picture description here
The above functions are almost also available in jconsole. VisualVM is more comprehensive and more intuitive. In addition, there are many other functions of VisualVM, which can analyze dump memory snapshots,
dump thread snapshots and analyze them, and there are many other plug-ins for you to explore
Insert picture description here

Actual combat

Prepare to simulate memory leak demo

​ 1. Define static variable HashMap

​ 2. Create objects in segments and add them to HashMap

​ The code is as follows:

import java.util.HashMap;
import java.util.Map;
public class CyclicDependencies {
    //声明缓存对象
    private static final Map map = new HashMap();
    public static void main(String args[]){
        try {
            Thread.sleep(10000);//给打开visualvm时间
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //循环添加对象到缓存
        for(int i=0; i<1000000;i++){
            TestMemory t = new TestMemory();
            map.put("key"+i,t);
        }
        System.out.println("first");
        //为dump出堆提供时间
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        for(int i=0; i<1000000;i++){
            TestMemory t = new TestMemory();
            map.put("key"+i,t);
        }
        System.out.println("second");
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        for(int i=0; i<3000000;i++){
            TestMemory t = new TestMemory();
            map.put("key"+i,t);
        }
        System.out.println("third");
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        for(int i=0; i<4000000;i++){
            TestMemory t = new TestMemory();
            map.put("key"+i,t);
        }
        System.out.println("forth");
        try {
            Thread.sleep(Integer.MAX_VALUE);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("qqqq");
    }
}

3. Configure the jvm parameters as follows:

         -Xms512m
         -Xmx512m
         -XX:-UseGCOverheadLimit
         -XX:MaxPermSize=50m

​ 4. Run the program and open visualvm monitoring

JVisualVM remotely monitor Tomcat

1. Modify the catalina.sh configuration file of remote tomcat and add:

  • JAVA_OPTS="$JAVA_OPTS
  • Djava.rmi.server.hostname=192.168.122.128
  • Dcom.sun.management.jmxremote.port=18999
  • Dcom.sun.management.jmxremote.ssl=false
  • Dcom.sun.management.jmxremote.authenticate=false"

This time the configuration does not go through permission verification. Just open the jmx port.

2. Open jvisualvm, right-click remote, and select add remote host:
Insert picture description here

3. Enter the name of the host and write ip directly, as follows:
Insert picture description here
Right-click the newly created host, select Add JMX connection, and enter the port configured in tomcat.

4. Double-click to open. complete!

Use JVisualVM to analyze memory leaks

1. Check the Visual GC tab. The content is as follows. This is a screenshot of the output first.
Insert picture description here
This is a screenshot of the output forth
Insert picture description here
. A comparison of the two images shows that the
Insert picture description here
Insert picture description here
old generation has been in gc. When the program continues to run, you can find that the old generation gc is still continuing:
Insert picture description here
increase It is 7 times, but the memory of the old generation has not decreased. It shows that there are objects that cannot be recycled. It may be a memory leak.
How to analyze that the object is leaked? Open the sampler tab: click as shown below:
Insert picture description here
follow the output of the program to dump the heap, when output second, dump once, when output later, dump once.
Enter the heap label from the last dump, click on the category:
Insert picture description here
click on the upper right corner: "Compare with another heap storage". As shown in the figure, select the first export dump content comparison: the
Insert picture description here
comparison results are as follows: it
Insert picture description here
can be seen that the TestMemory object instance has been increasing and more in the interval between the two times, indicating that the method referenced by the object may have a memory leak.
How to view the object reference relationship?
Right-click the class TestMemory and select "Show in Instance View", as shown below: the
Insert picture description here
left side is the total number of instances created, the upper right side is the structure of the instance, the following is the reference description, as can be seen from the figure in the class CyclicDependencies It is referenced and referenced by HashMap.

In this way, the location of the leak can be determined, and then analyzed and solved according to the actual situation.

How to perform JVM tuning

Observe memory release, collection class inspection, object tree

The above tuning tools all provide powerful functions, but in general they are generally divided into the following categories of functions

Heap information view

img

Can view the heap space allocation (young generation, old generation, persistent generation allocation)

Provide instant garbage collection

Garbage monitoring (monitoring the recycling situation for a long time)

img

View the class and object information in the heap. View: quantity, type, etc.

img

Object reference view

With the function of viewing heap information, we can generally solve the following problems smoothly:

-Is the size division of the old and young generations reasonable?

--Memory leak

-Whether the garbage collection algorithm setting is reasonable

Thread monitoring

img

Thread information monitoring: the number of system threads.

Thread state monitoring: what state each thread is in

img

Dump thread details: view the internal operation of the thread

Deadlock check

Hot spot analysis

img

Hot CPU : check the system which method takes a lot of CPU time

Memory hot spots : the maximum number of checks which objects (objects survive a certain time statistics and destroying objects together) in the system

These two things are very helpful for system optimization. We can search for the bottleneck of the system and optimize the system in a targeted manner based on the hotspots found, instead of aimlessly optimizing all codes.

Snapshot

A snapshot is a freeze frame of the system running to a certain moment. When we are tuning, it is impossible to track all system changes with our eyes. By relying on the snapshot function, we can make the difference between objects (or classes, threads, etc.) at two different runtimes of the system in order to find problems quickly

For example, I want to check whether any objects that should be recovered have been missed after the system has been garbage collected. Then, I can take a snapshot of the heap situation before and after garbage collection, and then compare the object situation of the two snapshots.

Memory leak check

Memory leakage is a relatively common problem, and the solution is also relatively general. Here we can focus on it, while the thread and hot issues are specific problems that are analyzed in detail.

Memory leaks can generally be understood as system resources (resources in all aspects, heap, stack, threads, etc.) in the case of incorrect use, resulting in the used resources cannot be recycled (or not recycled), resulting in the new resource allocation request cannot be completed , Causing a system error.

The memory leak is more harmful to the system, because it can directly cause the system to crash.

Need to distinguish, there is a difference between memory leak and system overload, although the end result may be the same. Memory leak is that the used up resources are not recovered and cause errors, while the system overload is that the system does not have so many resources to allocate (other resources are in use).

Old generation heap space is full

异常: java.lang.OutOfMemoryError: Java heap space

Description:

img

This is the most typical memory leak method. Simply put, all heap space is filled with garbage objects that cannot be recycled, and the virtual machine can no longer allocate new space.

As shown in the figure above, this is a very typical garbage collection picture of a memory leak. All peak parts are garbage collection points, and all bottom parts represent the memory remaining after a garbage collection. Connecting all the points of the valley bottom, you can find a line from bottom to high, which shows that over time, the system's heap space is constantly occupied, and eventually the entire heap space will be occupied. Therefore, it can be preliminarily considered that there may be a memory leak in the system. (The above picture is only an example, in actual situations it takes longer to collect data, such as several hours or days)

solve:

This method is also relatively easy to solve. Generally, it is based on the comparison of the situation before and after garbage collection, and the analysis based on the object reference situation (common collection object reference), and the leak can be basically found.

Persistent generation is occupied

**异常:**java.lang.OutOfMemoryError: PermGen space

Description:

Perm space is occupied. An exception caused by inability to allocate storage space for a new class. This exception did not exist before, but it is more common today when Java reflection is heavily used. The main reason is that a large number of classes generated by dynamic reflection are constantly being loaded, which eventually causes the Perm area to be full.

Even more frightening is that even if different classLoaders use the same class, they will all load it, which is equivalent to the same thing. If there are N classLoaders, it will be loaded N times. Therefore, in some cases, this problem is basically regarded as unsolvable. Of course, there are not many cases where there are a large number of classLoaders and a large number of reflection classes.

solve:

  1. -XX:MaxPermSize=16m

  2. Switch to JDK. Such as JRocket.

Stack overflow

**Exception: **java.lang.StackOverflowError

**Note:** I won’t say much about this, it is usually caused by recursion not returning or cyclic calling

Thread stack full

异常:Fatal: Stack size too small

Note : The space size of a thread in java is limited. After JDK5.0 this value is 1M. The data related to this thread will be stored in it. But when the thread space is full, the above exception will occur.

Solution : Increase the thread stack size. -Xss2m. But this configuration cannot solve the fundamental problem, and it depends on whether there is a leak in the code part.

System memory is full

异常:java.lang.OutOfMemoryError: unable to create new native thread

Description :

This exception is caused by the operating system not having enough resources to spawn this thread. When the system creates threads, in addition to allocating memory in the Java heap, the operating system itself also needs to allocate resources to create threads. Therefore, when the number of threads reaches a certain level, there may be space in the heap, but the operating system cannot allocate resources, and this exception occurs.

The more memory allocated to the Java virtual machine, the fewer remaining resources in the system. Therefore, when the system memory is fixed, the more memory allocated to the Java virtual machine, the fewer threads the system can generate. The relationship is inversely proportional. At the same time, you can reduce the space allocated to a single thread by modifying -Xss, and you can also increase the total number of threads produced in the system.

solve:

  1. Redesign the system to reduce the number of threads.

  2. If the number of threads cannot be reduced, use -Xss to reduce the size of a single thread. In order to be able to produce more threads.

JVM parameter optimization suggestions

Essentially, it reduces the number of GCs.

If it is an application that frequently creates objects, you can appropriately increase the size of the young generation. More constants can increase the persistent generation size. For objects with more singletons, the size of the old generation can be increased. For example, in spring applications.

GC selection, after JDK5.0, JVM will judge according to the current system configuration . Generally, execute the -Server command. gc includes three strategies: serial, parallel, and concurrent.

Throughput is greatly applied. Generally, parallel collection is used and multiple threads are turned on to speed up the gc.

Applications with high response speed generally use concurrent collection, such as application servers.

​ The old generation is recommended to be configured as a concurrent collector. Since the concurrent collector will not compress and defragment disks, it is recommended to configure:

​ -XX:+UseConcMarkSweepGC #Concurrently collect the old generation

​ -XX:CMSInitiatingOccupancyFraction=80 # Indicates that the CMS will be executed when the old generation space reaches 80%

​ -XX:+UseCMSCompactAtFullCollection # Turn on compression for the old generation. May affect performance, but can eliminate memory fragmentation.

​ -XX:CMSFullGCsBeforeCompaction=10 # Since the concurrent collector does not compress and organize the memory space, it will produce "fragments" after running for a period of time, which will reduce the operating efficiency. This parameter is set to compress and organize the memory space after running FullGC.

Guess you like

Origin blog.csdn.net/crazymakercircle/article/details/113758988