JVM in-depth notes (2) Simulation of memory overflow scenarios
- Author: Liu Da-poechant
- Email: zhongchao. USTC # gmail.com (#-> @)
- Blog: blog.csdn.net/poechant
- Date: Feb. 23St 2012
Deep JVM notes (1) How are memory areas divided? This article describes the division and Management of memory regions by JVM. In the actual programming process, some outofmemoryerror (OOM) situations are encountered. Through simulation, we can directly point the nature of these scenarios, so as to avoid coding in the complicated ten million lines of code. Oom may occur in many situations, including insufficient memory for Java or native method stack, stack overflow, heap
Memory overflow, non-heap memory overflow, and direct memory overflow.
Reference: Understanding Java Virtual Machine
1. Java method Stack Overflow Experiment
When will the Java method stack overflow occur? The basic feature of the stack is Filo (first in last out). If there are too many in and too few out, it is better to overflow. The Java method stack function saves the "field" of each callback function call, that is, the inbound stack. The function return corresponds to the outbound stack, so the deeper the function call, the Stack gets bigger and overflows when it is large enough. Therefore, to simulate Java method stack overflow, you only need to call a function recursively.
Program source code-1
// Author: Poechant// Blog: blog.csdn.net/poechant// Email: zhognchao.ustc#gmail.com (#->@)// Args: -verbose:gc -Xss128Kpackage com.sinosuperman.main;public class Test { private int stackLength = 0; public void stackOverflow() { ++stackLength; stackOverflow();} public static void main(String[] args) throws Throwable { Test test = new Test(); try { test.stackOverflow(); } catch (Throwable e) { System.out.println("stack length: " + test.stackLength); throw e; } }}
Running result
stack length: 1052Exception in thread "main" java.lang.StackOverflowError at com.sinosuperman.main.Test.stackOverflow(Test.java:8) at com.sinosuperman.main.Test.stackOverflow(Test.java:9) at com.sinosuperman.main.Test.stackOverflow(Test.java:9) at com.sinosuperman.main.Test.stackOverflow(Test.java:9) at com.sinosuperman.main.Test.stackOverflow(Test.java:9) ...
2. Java method stack memory overflow experiment heap memory overflow
Heap is used to store objects. Of course, objects do not always exist in the heap (due to the development of escape technology ). If the heap overflows, too many objects cannot be killed. Simulate heap memory overflow, as long as the object is constantly created and the reference exists.
Program source code-2
// Author: Poechant// Blog: blog.csdn.net/poechant// Email: zhongchao.ustc#gmail.com (#->@)// Args: -verbose:gc -Xmx50m -Xms50mpackage com.sinosuperman.main;import java.util.ArrayList;import java.util.List;public class Test { private static class HeapOomObject { } public static void main(String[] args) { List<HeapOomObject> list = new ArrayList<HeapOomObject>(); while (true) { list.add(new HeapOomObject()); } }}
Running result
[GC 17024K->14184K(49088K), 0.1645899 secs][GC 26215K->29421K(49088K), 0.0795283 secs][GC 35311K(49088K), 0.0095602 secs][Full GC 43400K->37709K(49088K), 0.1636702 secs][Full GC 49088K->45160K(49088K), 0.1609499 secs][GC 45312K(49088K), 0.0265257 secs][Full GC 49088K->49087K(49088K), 0.1656715 secs][Full GC 49087K->49087K(49088K), 0.1656147 secs][Full GC 49087K->49062K(49088K), 0.1976727 secs][GC 49063K(49088K), 0.0287960 secs][Full GC 49087K->49087K(49088K), 0.1901410 secs][Full GC 49087K->49087K(49088K), 0.1673056 secs][Full GC 49087K->316K(49088K), 0.0426515 secs]Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at com.sinosuperman.main.Test.main(Test.java:14)
3. Method Area memory overflow
That is, non-heap is used to store object class data, constants, static variables, and Code Compiled by JIT. If this region overflows, it means that a certain amount of data is created too much. You can create a new class until it overflows.
The following code uses cglib-2.2.2.jar and asm-all-3.0.jar.
Program source code-3
package com.sinosuperman.main;import java.lang.reflect.Method;import net.sf.cglib.proxy.Enhancer;import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy;public class Test { static class MethodAreaOomObject { } public static void main(String[] args) { while(true){ Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(MethodAreaOomObject.class); enhancer.setUseCache(false); enhancer.setCallback(new MethodInterceptor() { public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { return proxy.invoke(obj, args); } }); enhancer.create(); } }}
Running result
Exception in thread "main" net.sf.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException-->null at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:237) at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:377) at net.sf.cglib.proxy.Enhancer.create(Enhancer.java:285) at com.sinosuperman.main.Test.main(Test.java:24)Caused by: java.lang.reflect.InvocationTargetException at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at net.sf.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:384) at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:219) ... 3 moreCaused by: java.lang.OutOfMemoryError: PermGen space at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631) at java.lang.ClassLoader.defineClass(ClassLoader.java:615) ... 8 more
4. runtime constant pool in Method Area memory overflow
If a large number of constants are generated during the runtime, the method area can overflow. Running is a constant that can use the intern method of the string class to continuously generate new constants.
Program source code-4
package com.sinosuperman.main;import java.util.ArrayList;import java.util.List;public class Test { public static void main(String[] args) { List<String> list = new ArrayList<String>(); int i = 0; while (true) { list.add(String.valueOf(i++).intern()); } }}
Running result
Exception in thread "main" java.lang.OutOfMemoryError: PermGen space at java.lang.String.intern(Native Method) at com.sinosuperman.main.Test.main(Test.java:12)
Conclusion
Avoid such errors in actual encoding. However, the structure of most program designs is much more complex than the example here, so that the problem is hidden. However, most JVM memory overflow problems can be attributed to the above situations.
JVM in-depth notes (1) How are the memory areas divided? JVM in-depth notes (2) Simulation of memory overflow scenarios
-
For more information, see "LIU Da's csdn blog": blog.csdn.net/poechant
-