Program small white in the process of writing code, often inadvertently write a memory overflow exception occurred code. A lot of times this kind of anomaly how to produce all silly confused, if can deliberately write to let JVM memory overflow code, sometimes it seems not easy. Recently, by learning the deep understanding of Java Virtual Machine-JVM advanced features and best practices, I finally got a preliminary look at the memory model of the Java Virtual machine. This article summarizes your learning results by writing out code that causes the JVM to have a memory overflow exception, as well as reminding yourself not to jump into the hole when writing code.
Java's memory management is automatically managed by the Java Virtual machine, and does not require too much manual intervention by the programmer, which will lead to novice Java people who do not understand the Java memory model can also happily coding. However, if there is a memory leak or memory overflow and garbage collection (GC) problems, if you do not know how the virtual machine manages memory, then to troubleshoot the problem, the location of the wrong location is not at all. First look at what the data area looks like when the Java virtual computer is running (the image is from the network):
We can get the following information from us:
- The JVM memory partition can be divided into all threads shared data area and the thread isolation data area two parts. This means that the method area and heap in the diagram are used by all threads, while the virtual machine stack, the local method stack, and the program counter are unique to each thread's response data area, and the threads are not interfering with each other.
- The JVM runtime data area can be divided into method area, heap, virtual machine stack, local method stack, program counter five parts according to function. Each part stores different types of data.
This article focuses on how to make the JVM memory overflow exception, the JVM memory model will be explained in another article, here is a brief introduction to the role of each partition:
- Heap: Each thread is shared, the Java object instance is stored, and the space allocated for the array is here
- Virtual machine stack: Thread private, life cycle is the same as thread, describe the memory model executed by Java method, each method creates stack frame at execution time, stack frame stores local variable table, operand stack, dynamic link, return address (method exit) and other information
- Local method Stack: similar to the virtual machine stack, thread-private, serving the native method used by the virtual machine
- Method areas: Sharing of threads, storing information about classes that have been loaded by virtual machines, constants for final declarations, static variables of static modifiers, and data such as compiler-compiled Java code (Jdk7 later moved a constant pool to the heap )
- Program counter: Thread private, as a line number indicator of the bytecode of the program being executed by the current thread
In the JVM specification, in addition to the program counter memory area does not specify any memory overflow exception situation, the other four memory regions will have a corresponding memory overflow exception occurs, so the JVM memory overflow exception occurs in different memory regions have different causes of the exception, know the location of a memory anomaly, The location of the wrong place is very directional.
Here's an example of how to specify a memory overflow exception for different memory regions by code.
One, a memory overflow occurs in the Java heap:
The Java heap is used to store object instances and arrays, and the main thrust of a memory overflow in the Java heap is:
- Constantly creating objects
- Ensure that the object is alive and not reclaimed by the garbage collector
Java Virtual machine memory size can be set artificially, by setting the limit memory size, can easily implement memory overflow, save time.
The virtual machine parameter that sets the Java heap memory size is: The initial size of the-xms heap-xmx The maximum value of the heap extensibility
1 PackageTEXT.JVM;2 3Importjava.util.ArrayList;4Importjava.util.List;5 6/**7 * Java object instances are stored in JVM heap and array 8 * VM Args:-xms20m-xmx20m (limit heap size not extensible) 9 *@authorAdministrator10 **/12 Public classHeapoutofmemoryerror {13 14 Public Static classOomobject {15 }16 Public Static voidMain (string[] args) {List<object> list=NewArraylist<>();18//continuously create objects and ensure that GC roots to objects that have an accessible path to avoid garbage collection cleanup of objects created19 while(true) {List.add (Newoomobject ());21stSystem.out.println (System.currenttimemillis ());22 }23 }24 25}
View Code
JVM Virtual Machine startup parameter settings:
Operation Result:
Exception in thread ' main ' Java.lang.OutOfMemoryError:Java heap space at java.util.Arrays.copyOf (Arrays.java: 2245) at java.util.Arrays.copyOf (arrays.java:2219) at Java.util.ArrayList.grow ( Arraylist.java:242) at java.util.ArrayList.ensureExplicitCapacity (arraylist.java:216) At java.util.ArrayList.ensureCapacityInternal (arraylist.java:208) at Java.util.ArrayList.add (Arraylist.java:) at Text.JVM.HeapOutOfMemoryError.main (Heapoutofmemoryerror.java:20)
View Code
Note the end of the first line of the run result: java.lang.OutOfMemoryError: java heap space. Java heap Space explicitly indicates the area where the exception occurred: the heap.
Second, a memory overflow exception occurred on the virtual machine stack:
There are two scenarios in which a memory overflow exception can occur on a virtual machine stack:
- The stack depth of the thread request exceeds the maximum allowed depth of the virtual machine, and the Stackoverflowerror exception is thrown.
- A OutOfMemoryError exception is thrown when the virtual machine cannot request enough memory space on the scale stack.
The gist of a memory overflow exception that occurs on the Java Virtual machine stack:
- For Case 1, use unreasonable recursion
- corresponding to Scenario 2, create active threads continuously
Example of using recursion to cause a virtual machine stack memory overflow exception:
1 PackageTEXT.JVM;2 3 4/*5 * The stack depth of the thread request exceeds the maximum allowed depth of the virtual machine and will throw a Stackoverflowerror exception 6 * The most common case that causes such an exception is when using unreasonable recursive calls 7 * VM args:-xss256k 8 * 9 * @aut Hor Administrator10 **/12 Public classStackoverflowerror {13 14//log the stack depth when memory overflow15Private intStacklength = 1;16 17//methods for recursive calls18 Public voidStackleak () {stacklength++;20stackleak ();21st }22 23 Public Static voidMain (string[] args) {Stackoverflowerror Oomerror =Newstackoverflowerror ();26Try {27oomerror.stackleak ();28}Catch(Throwable e) {System.out.println ("Stack depth:" +oomerror.stacklength);30Throwe;31 }32 }33 34}
View Code
Program Run Result:
The stack depth is:2491 "main" Java.lang.StackOverflowError at Text.JVM.StackOverflowError.stackLeak ( Stackoverflowerror.java:(+) at Text.JVM.StackOverflowError.stackLeak (Stackoverflowerror.java: At Text.JVM.StackOverflowError.stackLeak (stackoverflowerror.java: Text.JVM.StackOverflowError.stackLeak (Stackoverflowerror.java:) ...
View Code
In the exception information:Java.lang.StackOverflowError indicates that the memory overflow area is the virtual machine stack.
Example of a memory overflow exception that caused a virtual machine stack by creating a thread:
1 PackageTEXT.JVM;2 3/*4 * Consumes virtual machine stack resources by constantly creating active threads 5 * VM args:-xss256k 6*/7 Public classStackoutofmemoryerror {8 9//thread tasks, each thread task is running10Private voidWontstop () {11 while(true) {12System.out.println (System.currenttimemillis ());13 }14 }15 16//constantly creating Threads17 Public voidStackleadbythread () {18 while(true) {Thread thread =NewThread (NewRunnable () {20 21@Override22 Public voidrun () {23wontstop ();24 }25 });26Thread.Start ();27 }28 }29 30 Public Static voidMain (string[] args) {Stackoutofmemoryerror oomerror=Newstackoutofmemoryerror ();32Oomerror.stackleadbythread ();33 }34 35}
View Code
In theory, the result of this code should be: Exception in thread "main" Java.lang.OutOfMemoryError: Unable to create new native thread , but because the Windows platform virtual machine Java thread is mapped to the kernel thread of the operating system, there is a greater risk that executing the above code may cause the operating system to feign death (I'm really dead), so run with caution!!! (wrote so long blog half did not save, restart after lost this I will talk nonsense??? It's all tears.
Three, method area and run constant pool memory overflow exception
The function of a method area is to store the structure information of a Java class, and when we create an object instance, the type information of the object is stored in the method area, the instance data is stored in the heap, and the instance data refers to the various instance objects created in Java and their values, and the type information refers to the constants defined in the Java code, Static variables, as well as the various methods, method fields, and so forth that are declared in the class, may include code data generated by the immediate compiler compilation. A method area memory overflow exception occurs when a large number of classes are generated at run time, or if the project itself has a large number of classes, and the space allocated by the method area is insufficient to accommodate so much class information.
Running a constant pool is part of the method, and the string literal used in the program and part of the base data type is stored in the constant pool. We use the String.intern () method to test that there is a memory overflow in the run-time-constant pool. The purpose of this method is if the string constant pool does not contain a string equal to this string object, the string contained by this object is added to the constant pool and a reference to this object is returned.
The gist of a memory overflow in the method area:
- A large number of classes created dynamically while the program is running, resulting in low method area memory space
- A large amount of literal data in the program causes the constant area to be out of memory
Constant pool memory Overflow sample code (only valid in versions prior to JDK6):
1 PackageTEXT.JVM;2 3Importjava.util.ArrayList;4Importjava.util.List;5 6/*7 * VM Args:-xx:permsize=10m-xx:maxpermsize=10m (limit constant pool capacity) 8 * 9*/10 Public classRuntimeconstantpooloutofmemoryerror {11 12 Public Static voidMain (string[] args) {13//use list to maintain constant pool references to avoid garbage collection of data in a constant poolList<string> List =NewArraylist<>();15Longi = 0;16 while(true) {Page string = (i++) + "";18List.add (String.intern ());19 }20 }21 22}
View Code
It is said that this code is generated in the previous version of Jdk6: Exception in Thread "main" Java.lang.OutOfMemoryError:PermGen space where PermGen space Indicates that a memory overflow occurred in the run-time-constant pool.
However, the result that I run in JDK7 environment is: Exception in thread "main" Java.lang.OutOfMemoryError:Java Heap space Indicates that a memory overflow occurred in the heap instead of a constant pool in the method area!!! It is true that practice is the only standard for testing truth. Because in the JDK1.2 ~ JDK6 implementation, the hotspot uses the permanent generation implementation method area, and the Oracle hotspot begins to remove the permanent generation from the JDK7,thesymbol table in JDK7 is moved to the Native heap, string constants and classes The reference is moved to the Java heap. in JDK8, the permanent generation has been completely superseded by the meta-space (meatspace). The storage location of the constant pool remains to be studied, but the previous code can cause a constant pool of memory overflow.
Generating a large number of class-generating method extents by running the memory overflow example is not available here, and the book provides an example of using Cglib to make a memory exception in the method area:
1/**2 * VM Args:-xx:permsize=10m-xx:maxpermsize=10m 3 *@authorZZM 4*/5 Public classJavamethodareaoom {6 7 Public Static voidMain (string[] args) {8 while(true) { 9 Enhancer Enhancer =Newenhancer (); Ten Enhancer.setsuperclass (Oomobject.class); Enhancer.setusecache (false); Enhancer.setcallback (NewMethodinterceptor () {13 PublicObject Intercept (Object obj, Method method, object[] args, Methodproxy proxy)throwsThrowable {14returnproxy.invokesuper (obj, args); 15 } 16 }); 17enhancer.create (); 18 } 19 } 20 21Static classOomobject {22 23 } 24}
View Code
Operation Result:
caused By:java.lang.OutOfMemoryError:PermGen space at java.lang.ClassLoader.defineClass1 (Native Method) At Java.lang.ClassLoader.defineClassCond (classloader.java:632) at Java.lang.ClassLoader.defineClass (Classloader.java:616)
View Code
I did not run this code, because I personally do not know about cglib, as long as the memory overflow is known to show:PermGen space that is the method area memory overflow is correct.
Iv. memory overflow exception due to insufficient direct memory
Direct memory is not part of the data area where the virtual machine is running, nor is it defined in the Java VM specification, but this part of the area is also frequently used, which can also lead to OutOfMemoryError
Direct memory is applied to NIO, the direct memory area defaults to the maximum memory value, by-xx:maxdirectmemorysize can explicitly specify the direct memory size, if the direct memory is ignored, it is easy to make the sum of each memory area greater than the physical memory limit, This causes a memory overflow when dynamic scaling occurs.
Specific code examples are not posted, because the usual learning process has not been used or have not realized that they have used the direct memory area.
(Note: The above content is solely to record the learning results, all the content is original, if you feel useful to welcome reprint, but please indicate the source, respect for the original, if the content of the text in the wrong place also please more advice)
How to write code that outofmemoryerror a Java virtual machine for a memory overflow exception