Object instantiation memory layout and access location
Object instantiation
Interview questions
- How are objects stored in the JVM?
- What's in the object header information?
- What's in the Java object header?
Starting from the method and steps of object creation
Object creation method
- new: The most common way to call the static class method of getInstance in the singleton class, the static method of XXXFactory
- Class's newInstance method: It is marked as obsolete in JDK9, because it can only call the empty parameter constructor
- Constructor's newInstance(XXX): reflection method, you can call the constructor with null parameters or with parameters
- Use clone(): do not call any constructor, and the current class needs to implement the clone interface in the Cloneable interface
- Use serialization: serialization is generally used for Socket network transmission
- Third-party library Objenesis
Steps to create an object
Determine whether the class corresponding to the object is loaded, linked, initialized
When the virtual machine encounters a new instruction, it first checks whether the parameter of this instruction can locate a symbolic reference of a class in the constant pool of Metaspace, and checks whether the class represented by this symbolic reference has been loaded, parsed and initialized. (That is, to determine whether the meta-information exists). If not, then in the parental delegation mode, use the current class loader to find the corresponding .class file with ClassLoader + package name + class name key. If the file is not found, a ClassNotFoundException will be thrown. If it is found, the class will be executed. Load and generate the corresponding Class object.
Allocate memory for the object
First calculate the size of the space occupied by the object, and then divide a block of memory in the heap for the new object. If the instance member variable is a reference variable, only the reference variable space can be allocated, which is 4 bytes in size
-
If the memory is regular: pointer collision
-
If the memory is not regular
- Virtual table needs to maintain a list
- Free list allocation
If the memory is regular, the virtual machine will use the Bump The Point method to allocate memory for the object.
It means that all used memory is on one side, and the free memory is stored on the other side. A pointer is placed in the middle as an indicator of the demarcation point. Allocating memory is just moving the pointer to the free side by a distance equal to the size of the object. If the garbage collector chooses Serial, ParNew, which is based on a compression algorithm, the virtual machine uses this allocation method. Generally, when using a collector with a Compact process, use pointer collision.
If the memory is not regular, the used memory and the unused memory are interleaved with each other, then the virtual machine will use the free list to allocate memory for the object. This means that the virtual machine maintains a list, and records those memory blocks that are available. When redistributing, find a large enough space from the list to divide the object instance and update the content on the list. This allocation method became the "Free List (Free List)"
The choice of allocation method is determined by whether the Java heap is regular or not, and whether the Java heap is regular or not is determined by whether the garbage collector used has a compression function.
Dealing with concurrency issues
- Use CAS with failed retry to ensure update atomicity
- Pre-allocate TLAB for each thread-set by setting -XX:+UseTLAB parameter (area locking mechanism)
- Allocate an area for each thread in the Eden area
Initialize allocated memory
Assignment of object properties
-
Default initialization of properties
-
Display initialization
-
Initialization in code block
-
Initializer
-
All properties are set to default values to ensure that the object instance fields can be used directly without assigning values
Set the object header of the object
Store the object's class (that is, the metadata information of the class), the object's HashCode, the object's GC information, lock information and other data in the object's object header. The specific setting of this process depends on the JVM implementation.
Execute the init method to initialize
From the perspective of a Java program, initialization has only officially begun. Initialize the member variables, execute the instantiated code block, call the constructor method of the class, and assign the first address of the object in the heap to the reference variable
So in general (determined by the invokespecial instruction in the bytecode), the new instruction will be followed by the execution method to initialize the object according to the programmer's wishes, so that a truly usable object is considered to be created.
Object instantiation process
- Load class meta information
- Allocate memory for the object
- Dealing with concurrency issues
- Default initialization of attributes (zero value initialization)
- Set object header information
- Display initialization of attributes, initialization in code block, initialization in constructor
Object memory layout
Object header
The object header contains two parts, namely runtime metadata (Mark Word) and type pointer
If it is an array, you also need to record the length of the array
Runtime metadata
- Hash Code (HashCode)
- GC generational age
- Lock status flag
- Locks held by threads
- Partial thread ID
- Flash timestamp
Type pointer
Point to the class metadata InstanceKlass to determine the type of the object. It actually points to the class meta information stored in the method area
Instance Data
Description
It is not necessary, and has no special meaning, only serves as a placeholder
summary
Object access location
Icon
How does the JVM access its internal object instances through the object references in the stack frame?
Two ways of object access
Handle access
Handle access refers to the reference of the recorded object in the local variable table of the stack, and then opens up a space in the heap space, that is, the handle pool
advantage
The reference stores the address of the stable handle. When the object is moved (it is common to move the object during garbage collection), only the instance data pointer in the handle can be changed, and the reference itself does not need to be modified.
Direct pointer (adopted by HotSpot)
The direct pointer is a reference in the local variable table, which directly points to the instance in the heap. There is a type pointer in the object instance, which points to the object type data in the method area.