Java programming common memory overflow exceptions and code examples, java programming overflow examples
Java heap is used to store object instances. Therefore, if we constantly create objects and ensure that there is a reachable path between GC Root and the created objects, the objects will not be garbage collected, when too many objects are created, the heap memory is insufficient, causing an OutOfMemoryError.
/** * @author xiongyongshun * VM Args: java -Xms10m -Xmx10m -XX:+HeapDumpOnOutOfMemoryError */public class OutOfMemoryErrorTest { public static void main(String[] args) { List<Integer> list = new ArrayList<>(); int i = 0; while (true) { list.add(i++); } }}
The above is a code that causes an OutOfMemoryError exception. We can see that it creates an object constantly and saves the object in the list to prevent it from being recycled by garbage collection. Therefore, when there are too many objects, the heap memory will overflow.
Through java-Xms10m-Xmx10m-XX: + HeapDumpOnOutOfMemoryError, we set the heap memory to 10 MB and use the parameter-XX: + HeapDumpOnOutOfMemoryError allows the JVM to print out the current memory snapshot when an OutOfMemoryError occurs for later analysis.
After compiling and running the above Code, the following output is displayed:
>>> java -Xms10m -Xmx10m -XX:+HeapDumpOnOutOfMemoryError com.test.OutOfMemoryErrorTest 16-10-02 23:35java.lang.OutOfMemoryError: Java heap spaceDumping heap to java_pid1810.hprof ...Heap dump file created [14212861 bytes in 0.125 secs]Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOf(Arrays.java:3210) at java.util.Arrays.copyOf(Arrays.java:3181) at java.util.ArrayList.grow(ArrayList.java:261) at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:235) at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:227) at java.util.ArrayList.add(ArrayList.java:458) at com.test.OutOfMemoryErrorTest.main(OutOfMemoryErrorTest.java:15)
Java stack StackOverflowError
We know that there is a memory area called the Virtual Machine stack in the JVM runtime data zone. The role of this area is that each method creates a stack frame during execution, stores information about local variable tables, operand stacks, and method exits.
Therefore, we can create an infinite recursive call. When the recursive depth is too large, the stack space will be exhausted, resulting in StackOverflowError.
The specific code is as follows:
/** * @author xiongyongshun * VM Args: java -Xss64k */public class OutOfMemoryErrorTest { public static void main(String[] args) { stackOutOfMemoryError(1); } public static void stackOutOfMemoryError(int depth) { depth++; stackOutOfMemoryError(depth); }}
After the above Code is compiled and run, the following exception information is output:
Exception in thread "main" java.lang.StackOverflowError at com.test.OutOfMemoryErrorTest.stackOutOfMemoryError(OutOfMemoryErrorTest.java:27)
Method Area memory overflow
Note that because JDK 8 has removed the permanent generation and replaced it with metaspace, in JDK 8, the following two examples do not cause java. lang. OutOfMemoryError: PermGen space exceptions.
Running frequent volume pool overflow
In Java 1.6 and earlier versions of the HotSpot JVM, there is a concept of permanent generation, that is, the GC generational collection mechanism is extended to the method area. in the method area, some memory is used to store the constant pool. Therefore, if there are too many constants in the Code, the memory of the constant pool will be exhausted, resulting in memory overflow. so how to add a large number of constants to the constant pool? In this case, you need to rely on String. intern () method. string. the intern () method is used to return the reference of the corresponding String in the constant pool if the value of this String already exists in the constant pool; otherwise, add the value contained in this String to the constant pool and return a reference to this String object. in JDK 1.6 and earlier versions, the constant pool is allocated in the permanent generation, so we can set the parameters "-XX: PermSize" and "-XX: maxPermSize to indirectly limit the size of the constant pool.
Note that the String. the memory distribution of the intern () method and constant pool is only applicable to JDK 1.6 and earlier versions. In JDK 1.7 or later versions, due to removing the concept of permanent generation, therefore, the memory layout is slightly different.
The following is an example of code to implement memory overflow in a constant pool:
/** * @author xiongyongshun * VM Args: -XX:PermSize=10M -XX:MaxPermSize=10M */public class RuntimeConstantPoolOOMTest { public static void main(String[] args) { List<String> list = new ArrayList<String>(); int i = 0; while (true) { list.add(String.valueOf(i++).intern()); } }}
In this example, the String. intern () method is used to add a large number of String constants to the constant pool, resulting in memory overflow in the constant pool.
We compile and run the above Code through JDK1.6, with the following output:
Exception in thread "main" java.lang.OutOfMemoryError: PermGen space at java.lang.String.intern(Native Method) at com.test.RuntimeConstantPoolOOMTest.main(RuntimeConstantPoolOOMTest.java:16)
Note that if you compile and run the above Code through JDK1.8, the following warning will be given without any exceptions:
>>> java -XX:PermSize=10M -XX:MaxPermSize=10M com.test.RuntimeConstantPoolOOMTest 16-10-03 0:23Java HotSpot(TM) 64-Bit Server VM warning: ignoring option PermSize=10M; support was removed in 8.0Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=10M; support was removed in 8.0
Method Area memory overflow
The method area stores information about the Class, such as the Class name, Class access modifier, field description, and method description. therefore, if the method area is too small and there are too many classes to load, it will cause memory overflow in the method area.
//VM Args: -XX:PermSize=10M -XX:MaxPermSize=10Mpublic class MethodAreaOOMTest { public static void main(String[] args) { while (true) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(MethodAreaOOMTest.class); enhancer.setUseCache(false); enhancer.setCallback(new MethodInterceptor() { public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { return methodProxy.invokeSuper(o, objects); } }); enhancer.create(); } }}
In the above Code, we use CGlib to dynamically generate a large number of classes. In JDK 6, running the above Code will generate an OutOfMemoryError: PermGen space exception:
/System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home/bin/java -jar -XX:PermSize=10M -XX:MaxPermSize=10M target/Test-1.0-SNAPSHOT.jar
The output result is as follows:
Caused by: java.lang.OutOfMemoryError: PermGen space at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClassCond(ClassLoader.java:637) at java.lang.ClassLoader.defineClass(ClassLoader.java:621) ... 11 more
MetaSpace memory overflow
In the memory overflow section of the method area, we mentioned that JDK 8 does not have the concept of permanent generation, so the two examples did not achieve the expected effect in JDK 8. in JDK8, is there any errors such as Method Area memory overflow? Of course. In JDK 8, MetaSpace is used to store Class-related information. Therefore, if MetaSpace has insufficient memory, a java. lang. OutOfMemoryError: Metaspace exception is thrown.
Let's take the example mentioned above as an example:
//VM Args: -XX:MaxMetaspaceSize=10Mpublic class MethodAreaOOMTest { public static void main(String[] args) { while (true) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(MethodAreaOOMTest.class); enhancer.setUseCache(false); enhancer.setCallback(new MethodInterceptor() { public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { return methodProxy.invokeSuper(o, objects); } }); enhancer.create(); } }}
The code in this example is not changed. The only difference is that we need to use JDK 8 to run this code and set the parameter-XX: MaxMetaspaceSize = 10 M, this parameter indicates that the maximum size of JVM Metaspace is 10 MB.
Next we use JDK 8 to compile and run this example. The output is as follows:
>>> java -jar -XX:MaxMetaspaceSize=10M target/Test-1.0-SNAPSHOT.jarException in thread "main" java.lang.OutOfMemoryError: Metaspace at net.sf.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:345) at net.sf.cglib.proxy.Enhancer.generate(Enhancer.java:492) at net.sf.cglib.core.AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator.java:114) at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:291) at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:480) at net.sf.cglib.proxy.Enhancer.create(Enhancer.java:305) at com.test.MethodAreaOOMTest.main(MethodAreaOOMTest.java:22)
Summary
The above is all the content about common memory overflow exceptions and code examples in Java programming. I hope to help you. If you are interested, you can continue to refer to other related topics on this site. If you have any shortcomings, please leave a message. Thank you for your support!