OOM problem in Java

What is OOM

OOM stands for "OutOfMemory", which means memory overflow. We know that objects in Java are created on the heap. When the heap memory is not enough to allocate space for the newly created object, OutOfMemoryError will be generated.

Why OOM

Because of the existence of the GC mechanism, Java programmers do not need to pay too much attention to the allocation and recovery of memory. The GC determines whether an object needs to be recovered through "reachability analysis".

Reachability analysis: The GC first determines a group of GC Root nodes (usually some global elements, such as objects held by the JVM), and then judges this object based on whether the GC Root holds a reference or reference chain pointing to an object Whether it is "reachable".

GC will recycle most useless objects. When OOM occurs, there are usually two cases:

  1. JVM heap memory is really insufficient
  2. Code issues

If there is insufficient heap memory, simply expand the heap memory. However, in most cases, OOM is caused by code problems, which means that many objects that should have been recycled have not been recycled, resulting in insufficient heap memory.

How to deal with OOM

  1. The key to dealing with the OOM problem is to get the Heap Dump (heap dump file), which saves the memory usage of objects in the JVM heap at a certain time. The Heap Dump file can be obtained by:

    • Before starting the program, add JVM parameters
    -XX:+HeapDumpOnOutOfMemoryError
    

    The meaning of this parameter is: When OOM occurs, a Heap Dump file is generated.

    • When the program is running, it is obtained through jmap. First get the pid of the Java process through jps, then output the dump file through jmap
    jmap -dump:live,format=b,file=<filepath> <pid>
    

    Where filepath is the location where the dump file is generated and pid is the pid of the Java process you want to analyze.

  2. After you get the dump file, you can use some graphical tools to analyze it. Commonly used graphic chemicals include visual VM, MAT, JProfiler, etc.

Give a chestnut

  1. First we write a program, and set the maximum heap memory of the JVM to 128M, so that it will OOM after a period of time, and use the vitual VM for simple analysis.
-Xmx128m
import java.util.ArrayList;
import java.util.List;

public class OOMExample {
    public static void main(String[] args) throws InterruptedException {
        List<byte[]> list = new ArrayList<>();
        for(int i=0;i<128;i++){
            list.add(new byte[1024*1024]);
            Thread.sleep(500);
        }
    }
}
  1. During operation, we can get the current process pid by typing jps on the command line. It can also be directly viewed through the vitual VM (I am trying to split the image twice so the pid is inconsistent).

image-20200422005307131

image-20200422005510311

  1. We can see the real-time running of the program through the vitual VM. Under normal circumstances, the memory curve of the program should be wavy, and our program is about to happen OOM.

img

  1. Get dump file through jmap
jmap -dump:live,format=b,file="/12844.hprof" 12844
  1. View dump files using vitual VM

image-20200422010042425

It is obvious that the byte array occupies most of the memory, which is consistent with our expectations. In actual scenarios, the object reference relationship of OOM is much more complicated than this. The specific analysis of specific problems and how to quickly find the problem code is also a problem.

Guess you like

Origin www.cnblogs.com/2511zzZ/p/12749312.html