Java Memory Overflow Analysis

Source: Internet
Author: User
Tags throwable xms

First, preface

Java's JVM's memory is generally divided into 3 zones: heap, Stack, and method area.

1.1 Heap Area

1) All objects are stored, each object contains a class corresponding to the information, the purpose of class is to obtain the operation instructions;

2) Only one heap area (heap) of the JVM is shared by all threads, and the heap does not hold basic types and object references, only the object itself.

1.2-Stack Area

1) Each thread contains a stack that holds only objects of the underlying data type and references to custom objects (not objects), and objects are stored in the heap area;

2) The data in each stack (original type and object reference) is private and other stacks cannot be accessed;

3) The stack is divided into 3 parts: the basic type variable area, the execution environment context, the operation instruction area (holds the operation instruction).

1.3 Method Area

1) also known as static or permanent generation, as in the heap, is shared by all threads. The method area contains all Class and static variables;

2) The method area contains elements that are always unique throughout the program, such as class,static variables;

3) The running constant pool is allocated in the Java virtual machine's method area, but from the beginning of the HotSpot virtual machine in JDK 1.7, the string constant pool that was originally placed in the permanent generation has been moved out.

Second, memory overflow analysis

The following code verifies that JDK 1.6 is recommended because the HotSpot virtual machine has improved a lot, especially the method area (permanent generation), starting with JDK 1.7.

2.1 Java Heap Overflow

The Java heap is used to store object instances, so as long as we create objects constantly and ensure that objects are not purged by the garbage collection mechanism, heap memory overflow occurs when the size of objects in the heap exceeds the maximum heap capacity limit.

Common exceptions to heap overflow are:Java.lang.OutOfMemoryError:Java Heap Space

The following code sets the size of the Java heap to 20MB and is not extensible (the-XMS parameter and the maximum value of the heap are set to equal 20MB to avoid automatic heap expansion); parameter-xx:+heapdumponoutofmemoryerror You can have the virtual machine generate a snapshot of the current memory heap in case of a memory overflow exception for later analysis, and the-VERBOSE:GC function is to display the information on the output device when the virtual machine has a memory recycle.

 PackageCom.java.error;Importjava.util.ArrayList;Importjava.util.List;/*** VM args:-verbose:gc-xms20m-xmx20m-xx:+heapdumponoutofmemoryerror * Error:java.lang.OutOfMemoryError:Java Heap Space *@authorMoonxy **/ Public classHeapoom { Public Static voidMain (string[] args) {List<HeapOOM> list =NewArraylist();  while(true) {List.add (Newheapoom ()); }    }}

The following is displayed after running:

[GC (Allocation Failure) 5380k->3745k (19968K), 0.0042158 secs] [GC (Allocation Failure) 9287k->9710k (19968K), 0.0058399 secs] [Full GC (ergonomics) 9710k->7589k (19968K), 0.1200134 secs] [Full GC (ergonomics) 16387k->12869k (19968K), 0.1112792 secs] [Full GC (ergonomics) 16428k->16382k (19968K), 0.1711686 secs] [Full GC (Allocation Failure) 16382k->16370k (19968K), 0.1371103 Secs]java.lang.outofmemoryerror:java Heap Spacedumping Heap to Java_pid1204.hprof ... Heap dump file created [28024534 bytes in 0.077 secs]exception in thread "main" Java.lang.OutOfMemoryError:Java Heap Spac Eat 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.java.error.OutOfMemoryJavaHeapSpaceTest.main (outofmemoryjavaheapspacetest.java:19) 

The console prints the OutOfMemoryError and prompts for a memory overflow in the Java heap and generates a dump file. For Java heap overflow, heap snapshot analysis of dump files is generally done through memory image analysis tools such as Eclipse Memory Analyzer, confirming that objects in memory are not necessary:

If the object is not necessary, it is a memory leak and needs to be analyzed why the object is not recycled;

If the object does need to continue to exist, it is a memory overflow that needs to be avoided by-xms the heap to a higher size (and -xmx).

Here's a comparison of memory leaks and memory overflows:

memory leak memories leak: Refers to the program after the application of memory, can not release the memory space has been applied, a memory leak does not seem to have a big impact, but the memory leak accumulation after the consequences of memory overflow;

memory overflowout of memory: An OOM error occurs when the program has applied for RAM and there is not enough memory for the requester to use or to store a long type of data into an int type of storage space.

2.2 Virtual machine stack and local method stack Overflow

Because the hotspot virtual machine does not differentiate between the virtual machine stack and the local method stack, the-xoss parameter (setting the local method stack size) is not valid for hotspot, and the stack capacity is set only by -XSS .

In the Java Virtual Machine specification, there are two exceptions to this area:

If the total size of the stack frame when the thread is running exceeds the size of the virtual machine limit, the Stackoverflowerror is thrown, which usually occurs when the stack overflow is easy to occur when the recursion runs:java.lang.StackOverflowError;

If the virtual machine stack is set to scale dynamically and cannot request enough memory when it is extended, OutOfMemoryError will be thrown, which is now easy to appear:java.lang.OutOfMemoryError:unable to create Native Thread.

Stackoverflowerror

/*** VM args:-xss128k * Error:java.lang.StackOverflowError *@authorMoonxy*/ Public classjavavmstacksof {Private intStacklength = 1;  Public voidStackleak () {stacklength++;    Stackleak (); }     Public Static voidMain (string[] args)throwsthrowable {javavmstacksof oom=Newjavavmstacksof (); Try{oom.stackleak (); } Catch(Throwable e) {System.out.println ("Stack Length:" +oom.stacklength); Throwe; }    }}

The following is displayed after running:

994Exception in thread "main" Java.lang.StackOverflowErrorat Com.java.error.StackOverflowTest.StackOver ( STACKOVERFLOWTEST.JAVA:15) at Com.java.error.StackOverflowTest.StackOver (stackoverflowtest.java:16) at Com.java.error.StackOverflowTest.StackOver (stackoverflowtest.java:16) at Com.java.error.StackOverflowTest.StackOver (stackoverflowtest.java:16) at Com.java.error.StackOverflowTest.StackOver (stackoverflowtest.java:16) ...

OutOfMemoryError

It is not recommended to perform the following validation, which is prone to fake animation, because Java threads are in the kernel thread that is mapped to the operating system in the Windows platform virtual machine.

/*** VM args:-verbose:gc-xss2m * Error:java.lang.OutOfMemoryError:unable to create native thread *@authorMoonxy **/ Public classJavavmstackoom {Private voidDontstop () { while(true) {                    }    }         Public voidStackleakbythread () { while(true) {thread thread=NewThread (NewRunnable () {@Override Public voidrun () {dontstop ();            }            });        Thread.Start (); }    }         Public Static voidMain (string[] args) {javavmstackoom oom=NewJavavmstackoom ();    Oom.stackleakbythread (); }}

The following is displayed after running:

Java.lang.OutOfMemoryError:unable to create new native thread

Threads need to consume stack capacity, and the operating system allocates memory for each process to be limited. Consider the following scenario: The total system memory 6G,JVM allocated 2G of memory, where the heap memory is allocated 1G, the method area (permanent generation) to allocate 512M, ignoring other smaller memory allocations, the remaining allocated to the virtual machine stack and the local method stack memory is only 512M, There is a good chance that there is not enough memory available to create many threads. The java.lang.OutOfMemoryError:unable to create new native thread is likely to appear. If this is the case, consider reducing the heap memory size or appropriately reducing the stack allocation size for each thread.

Threads consume memory, and if each thread consumes more memory, it will consume more memory overall. The default memory size per thread depends on the JVM implementation. You can use the-XSS parameter to limit the size of thread memory and reduce total memory consumption. For example, by default, the JVM consumes 1 m of memory per thread and the application has 500 threads, which consumes 500M of memory space. If you actually have enough 256K memory for the thread to run properly, configure-xss256k, then 500 threads will only consume 125M of memory. (Note that if the-XSS setting is too low, it will produce a java.lang.StackOverflowError error)

2.3 Method Area Overflow

The method area stores data such as the virtual machine loaded class information, constants, static variables, JIT compiler code and so on, before JDK1.7, the HotSpot is to use "permanent generation" to manage the data, that is, the method area of the data, in fact, is the heap memory, will occupy the heap memory.

Therefore: The data size of the method area <-xx:maxpermsize <-XMX

As long as we limit the size of the permanent generation (-xx:maxpermsize), it is easy to have a method area overflow, when the method area is easy to appear:java.lang.OutOfMemoryError:PermGen space. You can limit the method area size by setting-xx:permsize and-xx:maxpermsize.

/*** VM args:-verbose:gc-xx:permsize=10m-xx:maxpermsize=10m * Error:java.lang.OutOfMemoryError:PermGen space *@authorMoonxy **/ Public classOutofmemorypermgenspacetest { Public Static voidMain (string[] args) {List<String> oompgslist =NewArraylist<string>(); inti = 0;  while(true) {Oompgslist.add (string.valueof (i++). Intern ()); }    }}

After the run, the results are as follows:

Exception in thread "main" Java.lang.OutOfMemoryError:PermGen space

If we execute the same code above in the context of JDK 1.7, we will see that the while loop continues to execute. The reason is that in JDK 1.7, the HotSpot has no longer the constant in the permanent generation of management, but put into the memory limit is the native memory of the Native memories, the advantage is to reduce the chance of memory overflow (without the-xx:maxpermsize limit), At the same time, constants no longer consume heap memory. This "Go permanent" approach has started from JDK 1.7. Finally in JDK 1.8, was completely executed, the permanent generation was completely removed, and the HotSpot added a new area called Mataspace, and provided the-xx:metaspacesize and-xx:maxmetaspacesize parameters, to set the run Ja The initial capacity and maximum capacity of the metaspace used by the VA virtual machine.

2.4 Native Direct Memory overflow

Direct memory is not part of the data area when the virtual machine is running, nor is it an area of memory defined in the Java VM specification. But this part of the memory is also used frequently, but also may cause outofmemoryerror to appear, namely:java.lang.OutOfMemory.

The capacity of the native direct memory can be specified by -xx:maxdirectmemorysize , and if not specified, the default is the same as the Java heap maximum (-xmx specified).

One obvious feature of the native direct memory overflow is that the dump file is small because the main object is in direct memory, and the exception information does not indicate in which area the overflow occurred, like this: Java.lang.OutOfMemoryError

/*** * VM args:-verbose:gc-xx:maxdirectmemorysize * Error:java.lang.OutOfMemory *@authorMoonxy **/ Public classDirectmemoryoom {Private Static Final int_1MB = 1024 * 1024;  Public Static voidMain (string[] args)throwsException {Field Unsafefield= Unsafe.class. Getdeclaredfields () [0]; Unsafefield.setaccessible (true); unsafe unsafe= (Unsafe) unsafefield.get (NULL);  while(true) {unsafe.allocatememory (_1MB); }    }}

The results of the operation are as follows:

Exception in thread "main" Java.lang.OutOfMemoryError

In summary, the following JVM parameters can be set:

-xms256m-xmx1024m-xx:permsize=256m-xx:maxpermsize=512m

Java Memory Overflow Analysis

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.