Interview Talk-How to troubleshoot memory leaks

Interview Talk-How to troubleshoot memory leaks

JAVA's garbage collection mechanism gives programmers convenience, we don't need to explicitly release resources. But if you want to sit back and relax, you can’t. OOM is like a huanong hidden in the dark, threatening a poor, weak and beautiful programmer.

Generally speaking, a healthy program should not have OOM. The objects in memory are in order from birth to death. However, due to some human errors, some objects will often escape the sanctions of the GC, jump out of the GC, and not be in the trash. At this time, a memory leak occurred.

Memory leak means that the program does not release the allocated memory space after applying for memory and using up this memory (the object is no longer needed). A small number of occasional memory leaks, although not very good, but the problem is not big, and we will not search for that bit of memory. But if the memory continues to leak, until the new object does not have enough space to generate, it will lead to OOM.

When might a memory leak

Throw OOM exception

When the program throws OutOfMemoryError, if you think you are not too embarrassed and give the program enough space, then you can suspect a memory leak

Memory continues to rise

A healthy program should have a stable metabolism and memory usage should be maintained within a certain range. But if the memory continues to soar, or even reaches a dangerous value, then a memory leak can be suspected.

Check the GC situation

First get the pid of the application, you can use java jps command, or ps -ef|grep application name keyword

/**
 * Start an application and continue to create objects
 */
public class AcuptMain {

    public static void main(String[] args) throws InterruptedException {
        List<Liangzai> liangzais = new ArrayList<>();
        while (true) {
            liangzais.add(new Liangzai());
            Thread.sleep(1000);
        }
    }

    private static class Liangzai {
        byte[] body = new byte[1024 * 1024];
    }
}
//Execute the command jps to view the java process
➜ ~ jps
11617 Launcher
11618 AcuptMain
1353 RemoteMavenServer
1322 
11627 Jps
//According to the keyword view, the process id is 11618, which is the same as the one found by jps
➜ ~ ps -ef|grep acupt
  501 11618 1322 0 10:44 PM?? 0:00.39/Library/Java/JavaVirtualMachines...
# View the overall situation of gc, the usage rate of each district changes, updated every 3 seconds
➜ ~ jstat -gcutil 11618 3000 
  S0 S1 EOM CCS YGC YGCT FGC FGCT GCT
  0.00 0.00 56.20 0.00 17.39 19.90 0 0.000 0 0.000 0.000
  0.00 0.00 60.89 0.00 17.39 19.90 0 0.000 0 0.000 0.000
  0.00 0.00 65.58 0.00 17.39 19.90 0 0.000 0 0.000 0.000
  0.00 0.00 70.26 0.00 17.39 19.90 0 0.000 0 0.000 0.000
  0.00 0.00 74.95 0.00 17.39 19.90 0 0.000 0 0.000 0.000
  0.00 0.00 79.64 0.00 17.39 19.90 0 0.000 0 0.000 0.000
  0.00 0.00 84.33 0.00 17.39 19.90 0 0.000 0 0.000 0.000
  0.00 0.00 89.01 0.00 17.39 19.90 0 0.000 0 0.000 0.000
  0.00 0.00 93.70 0.00 17.39 19.90 0 0.000 0 0.000 0.000
  0.00 0.00 98.39 0.00 17.39 19.90 0 0.000 0 0.000 0.000
  0.00 98.48 5.02 26.91 79.14 82.73 1 0.021 0 0.000 0.021
  (The following is omitted...)

It can be seen that Eden (E) continues to create objects, and when it is full, the old age (O) increases, and the E area continues to create objects after being vacated. (The program is executed for a while, or the object creation speed is increased, and OOM will eventually be thrown)

View live objects

//Looking at the surviving objects, you can see that the byte array ranked first, and more observations will reveal that its number is also increasing
➜ ~ jmap -histo:live 11618

 num #instances #bytes class name
----------------------------------------------
   1: 644 103949616 [B
   2: 4342 416736 [C
   3: 4326 103824 java.lang.String
   4: 721 82056 java.lang.Class
   5: 746 49224 [Ljava.lang.Object;
   6: 738 29520 java.util.LinkedHashMap$Entry
   7: 609 19488 java.util.HashMap$Node
   8: 303 19392 java.net.URL
   9: 303 13560 [Ljava.lang.String;

According to the abnormal growth of surviving objects, analyzing where such objects are used in the program, you can also roughly infer the possible memory leaks.