Java memory area and memory overflow exception (ii)

Source: Internet
Author: User

After you understand the runtime data area of a Java virtual machine, you have a general overview of the virtual machine's memory, what's in memory, and then you'll learn about other details of the data in memory, how to create it, how to lay it out, and how to access it. Here the virtual machine takes hotspot as an example, the memory area takes the Java heap as an example to delve into the whole process of object assignment, layout and access in the Java heap by the hotspot virtual machine.

(i) Creation of objects

At the language level, creating objects (for example, cloning, deserialization) is usually just a new keyword, whereas in a virtual machine, the object (the object discussed in this article is confined to ordinary Java objects, not including arrays and class objects, etc.) is the process of creation.

Virtual opportunity to a new instruction, first check whether the parameter of this directive can locate the symbol reference of a class in the constant pool, and check whether the class that the symbol reference represents has been loaded, parsed and initialized. If not, you must first perform the appropriate class loading process.

After the class load check passes, the virtual machine allocates memory for the new object. The size of the memory required by an object is fully determined after the class is loaded, and the task of allocating space to an object is equivalent to dividing a size of memory from the Java heap. Assuming that the memory in the Java heap is absolutely regular, all the used memory is on one side, the free memory is on the other side, and a pointer is placed in the middle of the point indicator, the allocated memory is the pointer to the free space over there to move a section of the object size equal to the distance, this allocation is called "pointer collision."

If the memory in the heap is not regular, the memory used and the idle memory are interleaved, it is necessary to maintain a list of which memory blocks are available, to find a large enough space in the list to be allocated to the object instance at the time of allocation, and to update the records on the list, which is called the "Idle list".

The choice of which method is determined by whether the Java heap is structured, and whether the heap is structured or not, is determined by whether the garbage collector in use has a compression finishing function. Thus, when using collectors with compact processes such as serial, parnew, and so on, the allocation algorithm used by the system is a pointer collision, while the use of CMS, a collector based on the mark-sweep algorithm, usually takes a free list.

In addition to dividing the available space, consider thread safety. Object creation is a very frequent behavior in a virtual machine, and even if you modify the location pointed to by a pointer, it is not thread safe in the concurrency scenario, it is possible to allocate memory to object A, the pointer has not been modified, and object B uses the original pointer to allocate memory.

There are two ways to solve this problem, one is to synchronize the action of allocating the memory space--in fact, the virtual machine uses the CAs to match the failure retry to ensure the atomicity of the update operation, and the other is to divide the memory allocation action into different space according to the thread, That is, each thread pre-allocates a small chunk of memory in the Java heap, called the local thread allocation buffer (thread local Allocation buffer,tlab). Which thread allocates memory is allocated on the tlab of which thread, and only when Tlab runs out and assigns a new Tlab, does it require a synchronous lock. Whether the virtual machine uses Tlab and is set by the-xx:+/-usertlab parameter.

After the memory allocation is complete, the virtual machine needs to initialize the allocated memory space to a value of 0 (excluding the object header), and if Tlab is used, the work process can also be advanced to Tlab allocation. This operation guarantees that an instance field of an object can be used directly in Java code without assigning an initial value, and the program can access the 0 value corresponding to the data type of those fields.

Next, the virtual machines make the necessary settings for the object, such as which class the object is an instance of, how to find the metadata information of the class, the object's hash code, the object's GC band age, and so on. This information is placed in the object header of the object. Depending on the current running state of the virtual machine, such as whether biased locking is enabled, the object header can be set differently.

After the work is done, a new object has been created from the virtual machine's point of view, but from the Java program Point of view, the object creation has just begun-<init> method has not been executed, all fields are also 0. In general (determined by whether the bytecode is followed by the invokespecial directive), after executing the new instruction and then executing the <init> method, the object is initialized according to the programmer's will, so that a truly usable object is fully generated.

(add: The JVM itself is a layer of software abstraction on the hardware that can run Java programs, and we boast platform independence and Wora.) The JVM is a standard, the specific VM has dozens of kinds of implementations, this section is introduced by the implementation of the hotspot, while the mainstream VM including hotspot, Jikes RVM and so on, are based on C + + and assembly, each runtime compiled for each platform to compile, Therefore, when downloading the JRE is a sub-platform, the role of the VM is platform-independent. Class bytecode translated into platform-related machine code, to achieve cross-platform)

(ii) Memory layout of objects

In a hotspot virtual machine, the layout of objects stored in memory is divided into 3 regions: the object header (header), the instance data (Instance), and the alignment padding (Padding).

The object header consists of two pieces of information:

Object header The first part is used to store the object's own run-time data, such as hash code (HASHCODE), GC generational age, lock status flag, thread-held lock, biased thread ID, biased time stamp, etc. The length of this data is 32bit and 64bit, respectively, in 32-bit and 64-bit virtual machines (no compression pointers are turned on), officially known as "Mark Word". Objects need to store a lot of runtime data, in fact, has exceeded the 32-bit, 64-bit can record the limit, in view of the virtual machine space efficiency, Mark word design as a non-fixed data structure to store as much information in a very small space, it will be based on the state of the object to re-use their own storage space. For example, in a 32-bit hotspot virtual machine, if the object is unlocked, 25bit in Mark Word's 32bit space is used to store the object hash code, 4bit is used to store the object's generational age, 2bit is used to store the lock flag bit, 1bit is fixed to 0, In other states (lightweight lock, heavyweight lock, GC mark, biased) the contents of the object are stored as follows

The other part of the object header is the type pointer, which is a pointer to its class metadata, which the virtual machine uses to determine which class the object is an instance of. If the object is a Java array, the object header must also have a piece of data to record the length of the array, because the virtual machine can determine the size of the Java object through the metadata information of the ordinary Java object, but the array size cannot be determined from the array's metadata.

The next instance data section is the valid information that the object actually stores, as well as the various types of field content defined in the program code. Whether it is inherited from a parent class or defined in a subclass, it needs to be recorded. The order of storage is affected by the virtual machine Assignment policy parameters and the order in which the fields are defined in the Java source code. Hotspot virtual Machine The default assignment policy is Longs/doubles, INTs, Shorts/chars, Bytes/booleans, oops (ordinary Object Points), and fields with the same width are always assigned together. In cases where this precondition is met, the variables defined in the parent class appear before the child class. If the Compactfields argument is true, the narrower variable in the subclass may also be inserted into the void of the parent class variable.

The third part of the alignment fill does not necessarily exist, just play the role of placeholder. Since the automatic memory management system of the Hotspot VM requires that the object start address must be an integer multiple of 8 bytes, the size of the object must be an integer multiple of 8 bytes. The header portion of the object is exactly a multiple of 8 bytes (1 time times or twice times), so when the object instance data part is not aligned, it needs to be filled by aligning the padding.

(iii) Access and positioning of objects

Java programs need to manipulate the concrete objects on the heap through the reference data on the stack. The reference type only specifies a reference to the object in the Java Virtual Machine specification, and does not define the way in which the application locates and accesses the object in the heap, so depending on the implementation of the virtual machine, there are two ways to use the main access method, the handle and the direct pointer.

With a handle access, a chunk of memory is partitioned into the Java heap as the handle pool, where the handle of the object is stored, and the handle contains the specific address information of the object instance data and the type data reference.

If you use direct pointer access, the object's address is stored directly in the reference, and the Java heap object layout takes into account information about how to access the type data.

There are advantages to both approaches, and the greatest benefit of using a handle is that the reference store a stable handle address that changes only the instance data pointer in the handle when the object is moved (the behavior that is very common when the object is garbage collected), and reference itself does not need to be modified.

The benefits of using direct pointer access are fast, saving time spent on pointer positioning, and because object access is very frequent in Java, this overhead is a significant execution cost. For the hotspot virtual machine discussed in this book, it is accessed using a direct pointer.

Java memory area and memory overflow exception (ii)

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.