(i) Java memory area and memory overflow

Source: Internet
Author: User
Tags instance method

Memory model

the Java Virtual machine divides the memory he manages into several different data regions during the execution of a Java program. Includes: program counter, Java Virtual machine stack, local release stack, Java heap, method area.

Memory model


Program Counter

A smaller memory space, which is the line number indicator of the byte code executed by the current thread, and the bytecode interpreter works by changing the value of the counter to select the next byte-code instruction to be executed, and the basic functions such as branching, jumping, and looping are all dependent on it for implementation. each thread has a separate program counter, and the counters between the threads do not affect each other, so the zone is thread-private.

When a thread executes a Java method, the counter records the address of the executing virtual machine bytecode instruction, and when the thread executes the native method (called the local operating system method), the value of the counter is empty. In addition, the memory area is the only area in the Java Virtual Machine specification that specifies any oom (memory overflow: outofmemoryerror) condition.

 java VM Stack (Java Virtual machine Stacks)

The zone is also thread-private, and its life cycle is the same as the thread. The virtual machine stack describes the memory model that is executed by the Java method: Each time a method is executed, a stack frame is created, which is the data structure used to support the continuation of the virtual machine for method invocation and method execution. For the execution engine, in the active thread, only the stack frame at the top of the stack is valid, called the current stack frame, and the method associated with the stack frame is called the current method, and all bytecode instructions run by the execution engine operate on the current stack frame only. stack frames are used to store local variable tables, operand stacks, dynamic links, method return addresses, and some additional additional information. When compiling program code, the number of local variable tables required in the stack frame, the number of deep operand stacks are fully determined, and the code attribute of the method table is written. therefore, how much memory a stack frame needs to allocate is not affected by the program run-time variable data, but only by the specific virtual machine implementation.

In the Java Virtual Machine specification, two exceptions are specified for this area:

1. A Stackoverflowerror exception is thrown if the thread requests a stack depth that is greater than the depth allowed by the virtual machine.

2. If the virtual machine cannot request enough memory space in the dynamic expansion stack, the OutOfMemoryError exception is thrown.

There are some overlapping places: when the stack space cannot continue to be allocated, whether the memory is too small or the stack space used is too large, it is essentially just two descriptions of the same thing. In a single-threaded operation, either because the stack frame is too large or the virtual machine stack space is too small, when the stack space cannot be allocated, the virtual machine throws a Stackoverflowerror exception, and does not get the OutOfMemoryError exception. In a multithreaded environment, OutOfMemoryError exceptions are thrown.

The functions and data structures of each part of the information stored in the stack frame are described in detail below.  

1. Local variable table

A local variable table is a set of variable value storage spaces that are used to store the local variables defined in the method parameters and methods, where the type of data stored is the various basic data types that are known at compile time, Object references (reference) and ReturnAddress types (which point to the address of a bytecode directive). The memory space required for a local variable table is allocated during compilation, that is, when the Java program is compiled into a class file, the capacity of the maximum local variable table to be allocated is determined. When entering a method, this method needs to allocate how much local variable space in the stack is fully determined, and the local variable table size is not changed during the operation of the method.

The capacity of the local variable table is the smallest unit in the variable slot (slot). The virtual machine specification does not explicitly indicate the amount of memory space a slot should occupy (allowing it to change depending on the processor, operating system, or virtual machine), and a slot can hold a data type that is less than 32 bits: Boolean, Byte, char, short, int, float, reference and returnaddresss. Reference is the reference type of the object, and ReturnAddress is the service of the byte instruction, which executes the address of a bytecode instruction. For a 64-bit data type (long and double), the virtual opportunity assigns two contiguous slot spaces to it in the previous way.

The virtual machine uses the local variable table through index positioning, the range of index values is from 0 to the maximum number of slots in the local variable table, for 32-bit data type variables, index n for the nth slot, and for 64 bits, index n for Nth and n+1 two slots.

When the method executes, the virtual machine uses the local variable table to complete the pass of the parameter value to the parameter list, and if it is an instance method (not static), the slot of the No. 0-bit index in the local variable table defaults to the reference used to pass the object instance to which the method belongs, which can be passed through the keyword "this" To access this implicit argument. The remaining parameters are arranged in the order of the parameter tables, occupying a local variable slot starting at 1, and assigning the rest of the slots to the variable order and scope defined in the method body, after the parameter table has been allocated.

Slots in a local variable table are reusable, variables defined in the method body, scopes do not necessarily overwrite the entire method body, and if the value of the current bytecode PC counter exceeds the scope of a variable, the slot corresponding to that variable can be used by other variables. This design is not only to save space, in some cases, the reuse of the slot will directly affect the system and garbage collection behavior.

2, the operation of the stack

The operand stack is often called the Operation Stack, and the maximum depth of the operand stack is determined at compile time. the 32-bit data type occupies a stack capacity of 1,64 of 2 for the data type. When a method starts execution, its operation stack is empty, during the execution of the method, there will be various bytecode instructions (such as: add operation, assignment value, etc.) to the Operation Stack to write and extract content, that is, into the stack and the stack operation.

The Java Virtual machine's interpretation execution engine is called the "stack-based execution engine", where the "stack" is the operand stack. So we also call Java virtual machines stack-based, unlike Android virtual machines, which are register-based.

The main advantage of the stack-based instruction set is the portability, the main disadvantage is that the execution speed is relatively slow, and because the register is provided directly by the hardware, the main advantage of the register instruction set is the fast execution speed, the main disadvantage is the poor portability.

3. Dynamic Connection

Each stack frame contains a reference to the method in which the stack frame belongs to the running constant pool (described in the method area, later), and holds this reference to support dynamic connections in the method invocation process. A large number of symbolic references exist in the constant pool of the class file, and the method invocation directives in the bytecode are referenced as parameters to the symbol in the constant pool that points to the method. These symbolic references, some of which are converted to direct references (such as final, static, and so on) during the class loading phase or when they are first used, are called statically resolved, and the other part is converted to direct references during each run, which is called dynamic connections.

4. Method return address

When a method is executed, there are two ways to exit the method: The execution engine encounters a bytecode instruction returned by either method or encounters an exception, and the exception is not processed in the method body. Regardless of the exit mode, after the method exits, it is necessary to return to the location where the method was called before the program can continue execution. When the method returns, you may need to save some information in the stack frame to help restore the execution state of its upper-level method. In general, the method normally exits, the caller's PC counter value can be used as the return address, the stack frame is likely to save the counter value, and the method exits unexpectedly, the return address is to be determined by the exception handler, the stack frame is generally not save this part of the information.

The process of exiting the method is actually the same as putting the current stack frame out of the way, so the actions you might take when exiting are: Restoring the local variable table of the upper method and the operand stack, and, if there is a return value, pressing it into the operand stack of the caller's stack frame, adjusting the value of the PC counter to a directive following the method

   Local methods Stack (Native method Stacks)

This area is very similar to the virtual machine stack, except that the virtual machine stack executes Java method services for the virtual machine, while the local method stack is the local operating system (Native) method service that is used.

java Heap (Java heaps)

The Java heap is the largest chunk of memory managed by a Java virtual machine, which is a chunk of memory shared by all threads. almost all object instances and arrays allocate memory in this class. Java Heap is the main area of garbage collector management, so it is often referred to as the "GC heap".

According to the Java Virtual Machine specification, the Java heap can be in a physically discontinuous memory space, as long as it is logically contiguous. A OutOfMemoryError exception is thrown when there is no memory to allocate in the heap and the heap cannot be expanded.

method Area

method area is also a memory area shared by each thread that stores the class information that has been loaded by the virtual machine, Data such as constants, static variables, code compiled by the instant compiler, and so on. The Java Virtual Machine specification describes the method area as a logical part of the Java heap, and it does not require contiguous memory like java heap, can be either fixed size or extensible, and the virtual machine specification allows the zone to choose not to implement garbage collection. Garbage collection behavior is relatively rare in this area. The primary pin for memory reclamation in this area is the collection of discarded constants and useless classes. The run-time pool is part of the method area, and in addition to the description of the class's version, field, method, interface, and so on, there is a constant pool (class file constant pool), this part will be stored in the run-time pool of the method area after the class is loaded. Another important feature of running a constant pool with respect to the class file constants pool is dynamic, and the Java language does not require constants to be generated at compile time only, that is, the contents of a constant pool that is not pre-placed into a class file can be entered into the run constant pool of the method area. It is also possible to put new constants into the pool during run time, a feature that is exploited by developers to use the Intern () method of the String class.

According to the Java Virtual Machine specification, a OutOfMemoryError exception is thrown when the method area does not meet the memory allocation requirements.

Direct Memory

Direct memory is not part of the data area when the virtual machine is running, nor is it a memory area defined in the Java VM Specification, which is allocated directly from the operating system and therefore is not limited by the Java heap size, but is subject to the size of the total memory of the machine and the processor addressing space. Therefore it can also cause outofmemoryerror anomalies to appear. In JDK1.4, a new NIO mechanism is introduced, which is a new I/O method based on channel and buffer, which can allocate direct memory directly from the operating system, that is, allocating memory outside the heap, which can improve performance in some scenarios because it avoids replicating data back and forth in the Java heap and the native heap.

Memory Overflow

A simple test method for memory overflow in memory area is given below


one thing to focus on here is that, in multithreaded situations, the larger the memory allocated to each thread's stack, the more likely it is to generate a memory overflow exception. the operating system allocates a limited amount of memory per process, the virtual machine provides parameters to control the Java heap and the method area of the two parts of the maximum memory, ignoring the program counter consumption of memory (very small), and the process itself consumes memory, the rest of the memory is given to the virtual machine stack and the local method stack, The larger the stack capacity each thread allocates, the less the number of threads that can be established is natural. Therefore, if a memory overflow is caused by an excessive number of threads, it can only be exchanged for more threads by reducing the maximum heap and the stack capacity of each thread, in the case of fewer threads.

In addition, due to memory leaks in the Java heap, there is a brief explanation of the difference between memory leaks and memory overflows: Leak

Memory leaks mean that the allocated memory has not been recycled, resulting in a waste of resources due to the loss of control over that area of memory. There is no memory leak in Java, because garbage collector automatically reclaims garbage, but this is not absolutely, when we new object, and save its reference, but the back has been useless, and the garbage collector does not recycle it, this will cause memory leaks,

Memory overflow means that the memory required by the program exceeds the upper limit of memory (including dynamic scaling) that the system can allocate.


Object Instantiation Analysis

The most common example of memory allocation analysis is Object instantiation:

Object obj = new Object ();

The execution of this code involves the Java stack, theJava heap, and the three most important memory areas of the method area. Assuming that the statement appears in the method body and is used in a timely manner with Java that the JVM virtual machine does not understand, it should also be known that obj will be stored as a reference type (reference) in the local variable table of the Java stack, and the instantiated object of that reference will be saved in the Java heap. However, it may not be known that theJava heap must also contain address information (such as object types, parent classes, implemented interfaces, methods, and so on) that can find data for this object type, and these types of data are stored in the method area.

In addition, because the reference type specifies only a reference to the object in the Java Virtual Machine specification, and does not define the way in which the reference should be located, and the specific location of the objects in the Java heap, the object access methods implemented by different virtual machines will vary. There are two ways to access the mainstream: using a handle pool and using pointers directly.

Access through the handle pool is as follows:


access through direct pointers is as follows:


There are advantages to the way these two objects are accessed, and the greatest benefit of using handle access is that the stable handle address is stored in the reference, and only the instance data pointers in the handle are changed when the object is moved (garbage collection is a very common behavior when moving objects). and reference itself does not need to be modified. The biggest benefit of using direct pointer access is fast, which saves time overhead for pointer positioning. The currenthotspot virtual machine used by Java is the second way to access objects.

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

(i) Java memory area and memory overflow

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.