Let me teach you how to locate service memory overflow, see here

I often encounter such error logs at work: Are you at a loss and don’t know where to locate the problem?

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:3332)
at java.util.Arrays.copyOf(Arrays.java:3298)
at java.util.ArrayList.grow(ArrayList.java:265)
at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:239)
at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:231)
at java.util.ArrayList.add(ArrayList.java:462)
at MemoryLeakDemo.run(MemoryLeakDemo.java:12)
at MemoryLeakDemo.main(MemoryLeakDemo.java:20)

This is a memory overflow caused by improper object creation. This leads to frequent service exceptions.

The process of locating memory overflow

The following is the process of locating Java service memory overflow in general:

1. Confirm whether it is a memory overflow

First, we need to confirm whether the problem is caused by memory overflow. You can check the log file or console output of the Java service. If an error message similar to “OutOfMemoryError” appears, then you can confirm that the memory is overflowing.

2. Get stack trace information

When a memory overflow occurs, the JVM will automatically generate a dump file, and we can use tools (such as jmap, jstack) to obtain the stack trace information in the file. The stack trace can tell us which method or block of code caused the memory overflow.

3. Analyze the dump file

After getting the stack trace information, we need to analyze the dump file to determine which objects are taking up too much memory space. Dump files can be analyzed using tools such as MAT, VisualVM.

4. Optimize code

By analyzing the dump file, we can determine which method or code block caused the memory overflow. Next, we can optimize the code, reduce the creation of objects, release unnecessary resources, and so on.

Example of locating memory overflow

The following is a simple Java program to demonstrate the process of locating and troubleshooting memory overflow.

import java.util.ArrayList;
import java.util.List;

public class MemoryLeakDemo {

    private List<Object> list = new ArrayList<>();

    public void run() {
        while (true) {
            list.add(new Object());
            try {
                Thread. sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        MemoryLeakDemo demo = new MemoryLeakDemo();
        demo. run();
    }
}

The program will continue to add Object objects to a List, eventually leading to memory overflow. The following is the process of locating memory overflow:

1. Confirm whether it is a memory overflow

After running the program, the console outputs the following information:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:3332)
at java.util.Arrays.copyOf(Arrays.java:3298)
at java.util.ArrayList.grow(ArrayList.java:265)
at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:239)
at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:231)
at java.util.ArrayList.add(ArrayList.java:462)
at MemoryLeakDemo.run(MemoryLeakDemo.java:12)
at MemoryLeakDemo.main(MemoryLeakDemo.java:20)

It can be seen that the program has a memory overflow.

2. Get stack trace information

Use the jstack command to get stack trace information:

$ jstack -l 12345 > dump.txt

Among them, 12345 is the process ID of the Java service.

3. Analyze the dump file

Use the MAT tool to open the dump file, and you can see the following information:

It can be seen that the program creates a large number of Object objects and occupies a large amount of memory space.

Next, we can look at the object’s reference chain to find out which method or code block created these objects:

Please add image description

Please add image description

As you can see, these objects are created by the run method of the MemoryLeakDemo class.

4. Optimize code

According to the analysis results, we can determine that the run method caused the memory overflow. Next, we can optimize the code, such as limiting the size of the List, releasing unnecessary resources, and so on.

import java.util.ArrayList;
import java.util.List;

public class MemoryLeakDemo {

    private List<Object> list = new ArrayList<>();
    private int maxSize = 100000;

    public void run() {
        while (true) {
            if (list. size() >= maxSize) {
                list. clear();
            }
            list.add(new Object());
            try {
                Thread. sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        MemoryLeakDemo demo = new MemoryLeakDemo();
        demo. run();
    }
}

By limiting the size of the List, we can avoid memory overflow problems.

How to locate memory overflow

Memory overflow means that during the running of the program, the requested memory exceeds the memory size that the system can allocate, causing the program to crash or exit abnormally. For Java services, memory overflow is one of the more common problems. The following are some methods and steps for locating Java service memory overflow.

1. Start the service with JVM parameters

In order to locate the memory overflow problem, we need to add some specific JVM parameters when starting the service, so that the corresponding log information can be generated when the program has memory overflow. The following are some commonly used JVM parameters:

  • -Xmx: Set the maximum heap memory size
  • -Xms: Set the initial size of the heap memory
  • -XX:MaxPermSize: Set the maximum permanent generation memory size
  • -XX: + HeapDumpOnOutOfMemoryError: When the program has a memory overflow, generate a heap memory dump file
  • -XX:HeapDumpPath: Set the save path of the heap memory dump file

2. Analyze the heap memory dump file

When a memory overflow problem occurs in a Java service, you can locate the problem by analyzing the heap memory dump file. The heap memory dump file is generated when the JVM parameter -XX: + HeapDumpOnOutOfMemoryError is set to true. Here are some tools for analyzing heap dump files:

  • Eclipse Memory Analyzer Tool (MAT): MAT is an open source Java memory analyzer that can analyze heap memory dump files to find memory leaks and memory overflow issues.
  • VisualVM: VisualVM is a free Java performance analysis tool that can analyze heap memory dump files to find memory leaks and out-of-memory problems.
  • jhat: jhat is a command-line tool that comes with JDK. It can convert the heap memory dump file into HTML format, which is convenient for finding memory leaks and memory overflow problems.

3. Use code analysis tools

In addition to analyzing heap dump files, there are some code analysis tools that can be used to find memory leaks and out-of-memory issues. Here are some commonly used code analysis tools:

  • FindBugs: FindBugs is an open source static code analysis tool that can find potential defects and problems in Java code, including memory leaks and memory overflow issues.
  • PMD: PMD is an open source static code analysis tool that can find potential defects and problems in Java code, including memory leaks and memory overflow problems.
  • Checkstyle: Checkstyle is an open source static code analysis tool that can find potential defects and problems in Java code, including memory leaks and out-of-memory problems.

4. Summary

Locating Java service memory overflow issues requires the use of various methods and tools, including setting JVM parameters, analyzing heap memory dump files, and using code analysis tools. Through these methods and tools, the memory overflow problem can be quickly located and solved, and the stability and reliability of the service can be improved.