The content of this article is about the solution to Java exception OutOfMemoryError. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.
In the Java virtual machine specification description, in addition to the program counter, OOM exceptions may occur in several other running areas of the virtual machine memory. Here, we use code to verify what is stored in each runtime area and discuss how to handle it.
Java Heap Overflow
The Java heap is used to store object instances. As long as objects are continuously created, and there is a reachable path between GC Roots and the object to avoid garbage collection mechanism to clear these objects, then a memory overflow exception will occur after the number of objects reaches the maximum heap capacity limit.
Exception reproduction
The code uses the following virtual machine parameters:
-Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError
In this way, the size of the Java heap will be limited to 20 MB and cannot be expanded. The parameter -XX: HeapDumpOnOutOfMemoryError allows the virtual machine to dump the current memory heap dump snapshot for analysis when a memory overflow exception occurs.
Use the following code for verification:
public class HeapOOM { static class OOMObject { } public static void main(String[] args) { List<OOMObject> list = new ArrayList<OOMObject>(); while (true) { list.add(new OOMObject()); } } }
Running results:
java.lang.OutOfMemoryError: Java heap space Dumping heap to java_pid3460.hprof ... Heap dump file created [28199779 bytes in 0.237 secs]
The OOM exception of Java heap memory is a common memory in actual applications Overflow exceptions are often followed by the prompt "Java heap space" when they occur.
To solve the anomaly in this area, the general method is to first use a memory image analysis tool, such as MAT, to confirm whether there is a memory leak or a memory overflow.
If it is a memory leak, you can further use tools to view the reference chain from the leaked object to GC Roots to find out how the leaked object is associated with GC Roots and prevents the garbage collector from automatically recycling them. space.
If it is not a memory leak, in other words, the objects in the memory really need to survive, then you should check the heap parameters of the virtual machine and compare it with the physical memory of the machine to see if it can be increased. From a code perspective, check if there are situations where the life cycle of some objects is too long and the state holding time is too long. Try to reduce the memory consumption during the running of the program.
Since the virtual machine stack or the local method stack is not distinguished in the HotSpot virtual machine, for HotSpot, although the -Xoss parameter exists, In fact, it is invalid. The stack capacity is only set by the -Xss parameter.
In single thread, the code uses the following virtual machine parameters:
-Xss128k
Use this parameter to reduce the stack capacity, and use the following code to reproduce the exception:
public class JavaVMStackSOF { private int stackLength = 1; public void stackLeak() { stackLength++; stackLeak(); } public static void main(String[] args) throws Throwable { JavaVMStackSOF oom = new JavaVMStackSOF(); try { oom.stackLeak(); } catch (Throwable e) { System.out.println("stack length:" + oom.stackLength); throw e; } } }
If you use the default parameters of the virtual machine, the stack depth is in most cases (because the frame size pushed into the stack by each method is not the same, so it can only be said that in large In most cases) there is no problem reaching 1000 ~ 2000. For normal method calls (including recursion), this depth should be completely sufficient.
However, if memory overflow occurs due to the creation of too many threads, and if the number of threads cannot be reduced or a 64-bit virtual machine cannot be replaced, the only option is to reduce the maximum heap and stack capacity in exchange for more the rout.
Native direct memory overflow
DirectMemory capacity can be specified through -XX: MaxDirectMemorySize. If not specified, the default is the same as the Java maximum heap .
Use the following virtual machine parameters:
-Xmx20M -XX:MaxDirectMemorySize=10M
Use the following code to reproduce the exception:
public class DirectMemoryOOM { private static final int _1MB = 1024 * 1024; public static void main(String[] args) throws Exception { Field unsafeField = Unsafe.class.getDeclaredFields()[0]; unsafeField.setAccessible(true); Unsafe unsafe = (Unsafe) unsafeField.get(null); while (true) { unsafe.allocateMemory(_1MB);//直接申请分配内存 } } }
By An obvious feature of memory overflow caused by DirectMemory is that no obvious exceptions will be seen in the Heap Dump file.
If you find that the Dump file after OOM is very small, and NIO is used directly or indirectly in the program, then you can consider checking whether this is the reason.
The above is the detailed content of Solution to Java exception OutOfMemoryError. For more information, please follow other related articles on the PHP Chinese website!