Preface
In the previous article we learned about the structure of the Java Virtual machine and the Run-time data region, then we probably know the Java Virtual Machine memory profile, then the memory of how the data is created and accessed. This article will give you an answer.
1. Creation of objects
An object is usually created by a new object, and when the virtual machine receives a new instruction, it does the following.
(1) determine if the corresponding class of the object is loaded, linked, initialized
When a virtual machine receives a new command, it first checks whether the specified parameter can navigate to a class's symbolic reference in a constant pool, and checks whether the class represented by the symbolic reference has been loaded, linked, and initialized by the class loader. If not, the corresponding class loading process is performed first. About the ClassLoader we have mentioned in the previous article that there is no more to repeat.
(2) allocating memory for an object
After the class has finished loading, a chunk of memory is allocated to the object in the Java heap. Memory allocation depending on whether the Java heap is structured, there are two ways: pointer collisions: If the Java heap's memory is regular, that is, all the used memory is on one side, and the idle is on the other. Allocates memory by moving the pointer indicator in the middle to the free memory for a distance equal to the object's size. Idle list: If the memory of the Java heap is not regular, it is necessary for the virtual machine to maintain a list to record that memory is available, so that when allocated, you can query from the list to a large enough memory allocated to the object and update the list record after the assignment.
Whether the memory of the Java heap is structured depends on what is being used and whether the collector has a compression-finishing function, about the garbage collector, as described in the articles later in this series.
(3) Handling concurrent security issues
Creating objects is a very frequent operation, so you need to resolve concurrency problems in two ways: Synchronize the allocation of memory space, such as in the virtual machine with the CAS algorithm and the failure to retry the way to ensure the atomic nature of the update operation. Each thread allocates a small chunk of memory in the Java heap, known as the local thread allocation buffer (thread native allocation buffer), abbreviated to Tlab, which allocates memory on the tlab of the corresponding thread when the thread needs to allocate memory. When the Tlab in the thread is used up and assigned to the new Tlab, the synchronization lock is required. Use the-xx:+/-usertlab parameter to set whether the virtual machine uses Tlab.
(4) Initialization of allocated memory space
The memory to be allocated, except for the object header, is initialized to 0 values.
(5) Set the object header
Data such as the object's owning class, the object's Hashcode, and the object's GC generational age are stored in the object's header.
(6) Executing the Init method for initialization
Executes the Init method, initializes the member variables of the object, and invokes the constructor of the class, so that an object is created. 2. Heap Memory layout of objects
object is created, and memory has been allocated in the Java heap, how the object is laid out in heap memory.
Taking the hotspot virtual machine as an example, the layout of the object in heap memory is divided into three areas, namely the object header (header), the instance data (Instance), and the alignment fill (Padding). Object headers: The header includes two pieces of information, mark World and metadata pointers, mark World is used to store data for object runtime, such as hashcode, lock status Flags, GC generational age, and so on. The metadata pointer is used to point to the type information of the target class in the method area, and the metadata pointers can determine the specific type of the object. Instance data: Used to store various types of field information in an object, including inherited from the parent class. Align padding: the alignment fill does not have to exist, plays the role of placeholder, does not have special meaning.
The memory layout of the object is shown in the following illustration.
object Model for 3.HotSpot
The Oop-klass model is used in hotspot, which is a model for describing instances of Java objects, and OOP (ordinary object pointer) refers to the normal object pointer, and Klass is used to describe the specific type of object instance.
In hotspot, Instanceoopdesc and Arrayoopdesc are used to describe the object header, where the Arrayoopdesc object is used to describe the array type.
The code for INSTANCEOOPDESC is shown below.
Openjdk/hotspot/src/share/vm/oops/instanceoop.hpp
Class Instanceoopdesc:public Oopdesc {public://aligned header size. static int header_size () {return sizeof (instance OOPDESC)/heapwordsize; //If compressed, the offset of the fields of the instance May is aligned. static int base_offset_in_bytes () {//Offset computation code breaks if usecompressedclasspointers//only-True return (Usecompressedoops && usecompressedclasspointers)? Klass_gap_offset_in_bytes (): sizeof (INSTANCEOOPDESC); static bool Contains_field_offset (int offset, int nonstatic_field_size) {int base_in_bytes = Base_offset_in_bytes (); re Turn (offset >= base_in_bytes && (offset-base_in_bytes) < nonstatic_field_size * Heapoopsize); } }; |
You can see that Instanceoopdesc inherits from Oopdesc:
openjdk/hotspot/src/share/vm/oops/oop.hpp
Class Oopdesc {friend class vmstructs; private:volatile markoop _mark; Union _metadata {klass* _klass; Narrowklass _com Pressed_klass; } _metadata; Fast access to barrier set. Must be initialized. Static barrierset* _bs; ... } |
The OOPDESC contains two data members: _mark and _metadata. The Markoop type of _mark object refers to mark world as mentioned earlier. _metadata is a common body in which _klass is a normal pointer, and _compressed_klass is a compressed class pointer, which is the previously mentioned metadata pointer that points to the Instanceklass object, which describes the object's specific type.
The code for Instanceklass is shown below.
Openjdk/hotspot/src/share/vm/oops/instanceklass.hpp
Class Instanceklass:public Klass {... enum classstate {allocated,//allocated (but not yet linked) loaded,//Loaded A nd inserted in class hierarchy (but not linked yet) linked,//successfully linked/verified (but not initialized yet) Bein G_initialized,//currently running class initializer fully_initialized,//initialized (successfull final state) Initiali Zation_error//error happened during initialization}; ... } |
Instanceklass inherits from Klass, enumerated classstate is used to identify the loading progress of an object.
Knowing the Oop-klass model, we can analyze how the Java virtual machine finds the corresponding object instance through the object reference in the stack frame, as shown in the following figure.
As can be seen from the diagram, the Instanceoopdesc object in the Java heap is found through an object reference in the stack frame, and then the Instanceklass in the method area is determined by the metadata pointer in the INSTANCEOOPDESC to determine the specific type of the object.