Java Virtual machine learning-JVM memory Management: In-depth Java memory area with Oom (3)

Source: Internet
Author: User
Tags scalar

Overview

There is a high wall between Java and C + + that is surrounded by dynamic memory allocations and garbage collection techniques, and people outside the walls want to go in, but the people inside the wall want to come out.

For developers engaged in C, C + + program development, in the field of memory management, they are the highest power of the emperor is the most basic work of the working people-the "ownership" of each object, but also the beginning of each object of life to the end of the maintenance responsibility.

For Java programmers, there is no need to write paired delete/free for each new operation, it is not easy to have content leaks and memory overflow errors, and it looks like the JVM manages memory everything is fine. However, it is because Java programmers give the power of memory control to the JVM, in case of leaks and overflows, if you do not know how the JVM uses memory, then troubleshooting will be a very difficult thing.

VM Run-time data region

In the process of executing Java programs, the JVM uses a variety of data regions that have their own purpose, creation, and destruction times. According to the Java Virtual Machine Specification (second edition) (hereinafter referred to as VM spec), the JVM includes the following runtime data regions:

1. Procedure counter (program Counter Register):

Each Java thread has a program counter to hold which instruction executes to the current method, and for non-Native methods (Native interface local interface , C + +), this zone records the address of the VM primitive being executed. If the Natvie method is being executed, this area is empty (undefined). This memory area is the only area in the VM spec that does not specify any outofmemoryerror conditions.

2.Java VM Stack (Java virtual machine Stacks)

As with program counters, the life cycle of the VM stack is the same as the thread. The VM stack describes the memory model of the Java method call: When each method is executed, a frame is created to store the local variable table, the action stack, the dynamic link, the method exit, and so on. The call to completion of each method means that a frame is loaded into the stack in the VM stack. In the following article, we will focus on the local Variables table section of the VM stack.

Often some people make Java memory simple to the heap memory (heap) and stack memory (stack), the actual area is far more complex than this view, so the division is only a description of the variable definition is closely related to the memory area is the two blocks. The "heap" that is referred to is described later, and the "stack" refers to the local variable table portion of each frame in the VM stack. The local variable table holds the various scalar types (Boolean, Byte, char, short, int, float, long, double) that are known at compile time, object references (not the object itself, just a reference pointer), method return address, and so on. where long and double take up 2 local variable space (32bit), the remaining 1 are occupied. The local variable table is allocated when entering the method, and when entering a method, the method needs to allocate a large local variable in the frame as a matter of complete certainty, without altering the size of the local variable table during the run of the method.

This area is specified in the VM spec with an exception of 2: If the thread requests a stack depth greater than the virtual machine allows, the STACKOVERFLOWERROR exception will be thrown, if the VM stack can be dynamically extended (VM spec allows fixed-length VM stacks), The OutOfMemoryError exception is thrown when the extension cannot request enough memory.

3. Local methods Stack (Native method Stacks)

The local method stack works similarly to the VM stack, except that the VM stack runs the VM primitive service for the virtual machine, and the local method stack is the native method service that is used for the virtual machine. its implementation of the language, mode and structure is not mandatory, and even some virtual machines (such as Sun hotspot virtual machine) directly into the local method stack and the VM stack. As with the VM stack, this area also throws Stackoverflowerror and OutOfMemoryError exceptions.


4.Java Heap (Java heap)

For most applications, the Java heap is the largest piece of memory managed by a virtual machine. The Java heap is shared by all threads and is created when the virtual machine is started. The only purpose of the Java heap is to hold object instances where the vast majority of object instances are allocated. This is described in VM spec as: All instances and arrays are allocated on the heap (original: The heap is the runtime data area from Whichmemory for all class instances and arrays is allocated), but the description of the VM spec is less accurate after the escape analysis and the scalar substitution optimization techniques appear.

The Java heap also has finer divisions: The new generation, the old, and the finer: Eden, from-survivor, to-survivor, and even finer-grained local thread allocation buffers (TLAB), no matter how the Java heap is partitioned, is designed to better reclaim memory. or faster allocation of memory, in this chapter we only discuss the role of memory area, the details of each of the above areas in the Java heap can be found in chapter II, "JVM memory Management: In-depth garbage collector and memory allocation policy."

Depending on the requirements of the VM spec, the Java heap can be in a physically discontinuous memory space, which is logically contiguous, just like our disk space. Implementations can be either fixed-size or extensible, but all commercially available virtual machines are extensible (via-XMX and-xms controls). " If memory cannot be allocated in the heap and the heap can no longer be expanded, an outofmemoryerror exception will be thrown.

5. Method area

It's not too many people called the "method area" who might know it, and if it's called a permanent generation (Permanent Generation) Its fans may be more. It also has an individual name called NON-HEAP (not a heap), but the VM spec describes the method area as a logical part of the heap (the original: Themethod zone is logically parts of the heap), the name of the problem is really easy to cause misunderstanding, We don't get tangled up here.

The method area contains the structure information for each class, including constant pools, field descriptions, method descriptions, and so on. The restrictions on this area in the vmspace description are very loose, with the exception of the Java heap, which does not require contiguous memory, can be either fixed size or extensible, and can even choose not to implement garbage collection. Relatively speaking, the garbage collection behavior in this area is relatively small occurrence, but not some of the description of the permanent generation will not occur GC (at least for the current mainstream commercial JVM implementation is so), here the GC is mainly for the constant pool of recycling and unloading classes, although the recovery of "score" is generally less than satisfactory, Especially class unloading, the conditions are quite harsh.

6. Run a constant pool (runtime Constant)

class file In addition to the class version, fields, methods, interfaces and other information such as descriptions, there is also a constant table (Constant_pool table), for the compilation of the known constants, which will be loaded in the class load into the method area (permanent generation) storage. However, the Java language does not require constants to enter the method area constant pool only if the content of the const table of the class is pre-compiled, and the new content can be put into Chang (the most typical String.intern () method) during the run time.

The run-time constant pool is part of the method area and is naturally constrained by the memory of the method area, which throws a OutOfMemoryError exception when the constant pool fails to request memory.

7. Native Direct Memory

Direct memory is not part of the data area when the virtual machine is running, it is simply the native memory and not the area that the VM directly manages. But this part of the memory also causes OutOfMemoryError to appear, so let's put it together to describe it.

In JDK1.4, a new NiO class is introduced, which introduces a channel-to-buffer I/O approach, which can allocate native memory directly through the native native library, and then operate through a Directbytebuffer object stored in the Java heap as a reference to this memory. This can significantly improve performance in some scenarios because it avoids copying data back and forth between Java pairs and the native heap.

Obviously the allocation of the local direct memory is not limited by the Java heap size, but that is the memory that must still be subject to the local physical memory (including swap area or Windows virtual memory) restrictions, the General server administrator configuration JVM parameters, according to the actual memory settings-xmx parameters such as information, However, it is often overlooked that direct memory causes the sum of each memory region to be greater than the physical memory limit (including physical and operating system-level limitations), and OutOfMemoryError exceptions occur when dynamic scaling occurs.

Combat OutOfMemoryError

In the above area, in addition to the program counters, other in the VM spec describes the generation of OutOfMemoryError (hereinafter referred to as Oom) situation, then we simulated the actual combat, through a few simple code, so that the corresponding region generated oom anomaly in order to deepen understanding, Some memory-related virtual machine parameters are also introduced. The following code is based on the implementation of the Sun Hotspot virtual machine version 1.6, and for different versions of the virtual machines in different companies, the parameters and the results of the program run may differ.

Java Heap

The Java heap holds object instances, so you can create an Oom exception by constantly building objects and ensuring that the GC roots to a path between objects. The test restricts the Java heap size to 20M, is not extensible, and allows the virtual machine to dump the memory image for analysis when an oom exception occurs through the parameter-xx:+heapdumponoutofmemoryerror. (For dump image file analysis, see chapter III, "JVM memory Management: In-depth JVM memory anomaly analysis and tuning.") )

Checklist 1:java Heap Oom test

/*** VM Args:-xms20m-xmx20m-xx:+heapdumponoutofmemoryerror *@authorZzm*/ Public classHeapoom {Static classOomobject {} Public Static voidMain (string[] args) {List<OOMObject> list =NewArraylist<oomobject>();  while(true) {List.add (Newoomobject ()); }       }}

Run results

Java.lang.OutOfMemoryError:Java heap spacedumping heap to java_pid3404.hprof ... Heap dump file created [22045981 bytes in 0.663 secs]

VMS stack and local method stacks

The hotspot virtual machine does not differentiate between the VM stack and the local method stack, so the-xoss parameter is effectively invalid and the stack capacity is set only by the -xss parameter. About the VM stack and the local method stack describes two exceptions in VM Spec: Stackoverflowerror and OutOfMemoryError, when the stack space is unable to continue allocating allocations, whether the memory is too small or the stack is too large in fact, in a sense, is the same thing in two kinds of description, in the author's experiment, for single-threaded application attempt the following 3 methods can not let the virtual machine to produce oom, all of the results are to obtain SOF exception.

1. Use the-XSS parameter to reduce the stack memory capacity. Result: The stack depth of the thrown SOF exception shrinks accordingly.

2. Define a large number of local variables and increase the length of the corresponding frame for this method. Result: The stack depth of the thrown SOF exception shrinks accordingly.

3. Create several complex objects that define many local variables, open the escape analysis and scalar substitution options so that the JIT compiler allows the object to be split and allocated in the stack. Results: The actual effect was the same as the 2nd.

Checklist 2:VM Stack and local method stack Oom test (only as the 1th test program)

/*** VM args:-xss128k *@authorZzm*/ 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; }       }}


Results

Stack length:2402"main" Java.lang.StackOverflowError        at Org.fenixsoft.oom.JavaVMStackSOF.stackLeak (Javavmstacksof.java:) at        Org.fenixsoft.oom.JavaVMStackSOF.stackLeak (Javavmstacksof.java:+)        at Org.fenixsoft.oom.JavaVMStackSOF.stackLeak (Javavmstacksof.java:21)

If in the multi-threaded environment, the constant establishment of threads can produce oom exception, but basically this exception and VM stack space is not enough relationship is not directly related, even to the VM stack for each thread the more memory allocated to the more likely to produce this oom exception.

The reason is really good to understand that the operating system assigned to each process of memory is limited, such as 32-bit Windows limit to 2g,java heap and the size of the method area JVM has parameters can limit the maximum value, The remaining memory is 2G (operating system limit)-XMX (maximum heap)-maxpermsize (maximum method area), the program counter consumes a small amount of memory, can be ignored, the virtual machine process itself is consumed by the memory is not calculated, the remaining memory for each thread of the VM stack and the local method stack partition, The more memory the VM stack allocates in each thread, the easier it will be to drain the remaining memory.

Listing 3: Creating a thread causing an oom exception

/*** VM args:-xss2m (may be larger at this time) *@authorZzm*/ 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)throwsthrowable {javavmstackoom oom=NewJavavmstackoom ();       Oom.stackleakbythread (); }}

In particular, if the reader is to run the above code, remember to save the current work, the above code execution has a great risk to the operating system card death.

New Native Thread

Run a constant-rate pool

The simplest way to add content to a constant pool is to use the String.intern () native method. because the constant pool is allocated within the method area , we only need to limit the size of the constant pool by limiting the method area by-xx:permsize and-xx:maxpermsize. The implementation code is as follows:

Listing 4: Oom exceptions caused by running a constant pool

/*** VM args:-xx:permsize=10m-xx:maxpermsize=10m *@authorZzm*/ Public classRuntimeconstantpooloom { Public Static voidMain (string[] args) {//use list to keep constant pool references, suppress full GC recycle constant pool behaviorlist<string> list =NewArraylist<string>(); //The 10M permsize is enough to generate oom in the integer range.              inti = 0;  while(true) {List.add (string.valueof (i++). Intern ()); }       }}

Results

Exception in thread "main" java.lang.OutOfMemoryError:PermGen space at       Java.lang.String.intern (Native Method) At       Org.fenixsoft.oom.RuntimeConstantPoolOOM.main (Runtimeconstantpooloom.java:18)

Method area

As mentioned above, the method area is used to store class-related information, so this area of the test we use Cglib directly manipulate bytecode dynamically generated a large number of classes, it is worth noting that here in our example, the simulation of the scene is often in the actual application of the appearance: a lot of mainstream framework, such as spring and Hibernate, when the class is enhanced, will use to cglib this kind of bytecode technology, when the enhanced class more, it will need the larger method area to ensure that the dynamically generated class can be loaded into memory

Listing 5: Using Cglib to make an Oom exception in the method area

/*** VM Args:-xx:permsize=10m-xx:maxpermsize=10m *@authorZzm*/ Public classJavamethodareaoom { Public Static voidMain (string[] args) { while(true) {Enhancer enhancer=Newenhancer (); Enhancer.setsuperclass (oomobject.class); Enhancer.setusecache (false); Enhancer.setcallback (NewMethodinterceptor () { PublicObject Intercept (Object obj, Method method, object[] args, Methodproxy proxy)throwsThrowable {returnproxy.invokesuper (obj, args);                     }                     });              Enhancer.create (); }       }        Static classoomobject {}}
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)       8 more

Native Direct Memory

Directmemory capacity can be specified by-xx:maxdirectmemorysize, not specified by default as the Java heap (-xmx specified), the following code crosses the Directbytebuffer, Get an unsafe instance directly from reflection for memory allocation (the Getunsafe () method of the unsafe class restricts only the boot class loader from returning instances, That is, basically only the Rt.jar inside the class can be used), because Directbytebuffer will also throw an Oom exception, but the exception is thrown when actually did not really apply to the operating system to allocate memory, but by calculating that the inability to allocate both thrown, the actual application of the allocation method is Unsafe.allocatem Emory ().

/*** VM args:-xmx20m-xx:maxdirectmemorysize=10m *@authorZzm*/ 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); }       }}

Results

Exception in thread "main" Java.lang.OutOfMemoryError at       sun.misc.Unsafe.allocateMemory (Native Method)       At Org.fenixsoft.oom.DirectMemoryOOM.main (Directmemoryoom.java:20)
Summarize

So far, let's figure out how the memory in the virtual machine is divided, what part of the area, what kind of code, operations can cause an OOM exception. Although Java has a garbage collection mechanism, but oom is still not far away from us, this chapter we just know the reason for the occurrence of oom in each region, the next chapter we will look at the Java garbage collection mechanism in order to avoid the occurrence of oom anomalies, and what efforts have been made.

Java Virtual machine learning-JVM memory Management: In-depth Java memory area with Oom (3)

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.