Java virtual machine object creation process and initialization process

Preface

Sort out the object creation process and initialization process

Java virtual machine runtime data area

Object creation process

Object creation

  1. When the new instruction is used, locate the symbol reference of the parameter of the instruction in the constant pool
  2. If not, load, connect and initialize the class.
  3. The virtual machine allocates memory for newborn objects
  4. Initialize the allocated memory space to zero, excluding the object header, and initialize the object header (hash code, gc age, etc.)
  5. Call object method

1. Class loading process

In-depth understanding of the Java virtual machine Chapter 7 virtual machine class loading timing and process

2. Object memory layout

The layout of objects in memory is divided into three areas: object header, instance data, and alignment padding.

1. Object Head

The object header of the Hotspot virtual machine mainly includes two parts of data: Mark Word (marked field) and Klass Pointer (type pointer). The array will be 1 word wide (32 bits: 4 bytes) to store the length of the array.

  • Mark Word is used to store the runtime data of the object itself, it is the key to realize lightweight lock and bias lock.
  • Klass Point is a pointer to the object's class metadata, and the virtual machine uses this pointer to determine which class instance the object is;

2. Example data

This part is the effective information that the object actually stores, and it is also the content of various types of fields defined in the program code, including those inherited from the parent class and those defined in the subclass.

3. Align and fill

This part is not necessary. Some virtual machines require that the starting address of the object must be an integer multiple of 8 bytes, that is, the size of the object must be an integer multiple of 8 bytes, so alignment is required when insufficient.

4. Detailed Explanation of Mark Word

There are two ways of object header in JVM (take 32-bit JVM as an example):

// 普通对象
|--------------------------------------------------------------|
|                     Object Header (64 bits)                  |
|------------------------------------|-------------------------|
|        Mark Word (32 bits)         |    Klass Word (32 bits) |
|------------------------------------|-------------------------|

// 数组对象
|---------------------------------------------------------------------------------|
|                                 Object Header (96 bits)                         |
|--------------------------------|-----------------------|------------------------|
|        Mark Word(32bits)       |    Klass Word(32bits) |  array length(32bits)  |
|--------------------------------|-----------------------|------------------------|

  • This part of Mark Word is mainly used to store the runtime data of the object itself, such as hashcode, gc generation age, lock status flag, lock held by the thread, biased thread ID, biased timestamp, etc.
    The bit length of the mark word is the size of one word of the JVM, which means that the mark word of a 32-bit JVM is 32 bits, and a 64-bit JVM is 64 bits.
    Mark Word is designed as a non-fixed data structure to store as much data as possible in a very small memory space. It reuses its own storage space according to the state of the object. In order to store more information in a word size, JVM will The lowest two bits of the word are set as mark bits, and the Mark Word under different mark bits is shown as follows:
|-------------------------------------------------------|--------------------|
|                  Mark Word (32 bits)                  |       State        |
|-------------------------------------------------------|--------------------|
| identity_hashcode:25 | age:4 | biased_lock:0 |lock:01 |     Normal无锁      |
|-------------------------------------------------------|--------------------|
|  thread:23 | epoch:2 | age:4 | biased_lock:1| lock:01 |     Biased偏向锁    |
|-------------------------------------------------------|--------------------|
|               ptr_to_lock_record:30         | lock:00 | Lightweight Locked轻量级锁 |
|-------------------------------------------------------|--------------------|
|               ptr_to_heavyweight_monitor:30 | lock:10 | Heavyweight Locked重量级锁 |
|-------------------------------------------------------|--------------------|
|                                             | lock:11 |    Marked for GC   GC标记|
|-------------------------------------------------------|--------------------|

Lock state

  • lock: 2-bit lock status flag bit. Since we want to use as few binary bits as possible to represent as much information as possible, the lock flag is set. The value of the mark is different, the meaning of the whole mark word is different.
  • biased_lock: Whether the object enables the biased lock flag, which only occupies 1 binary bit. When it is 1, it means that the object has a biased lock; when it is 0, it means that the object has no biased lock.
  • age: 4-digit Java object age. In the GC, if the object is copied once in the Survivor area, the age increases by 1. When the subject reaches the set threshold, it will be promoted to the old age. By default, the age threshold for parallel GC is 15, and the age threshold for concurrent GC is 6. Since age has only 4 bits, the maximum value is 15, which is why the maximum value of the -XX:MaxTenuringThreshold option is 15.
  • identity_hashcode: 25-bit object identification hash code, using lazy loading technology. Call the method System.identityHashCode() to calculate and write the result to the object header. When the object is locked, the value will be moved to the monitor monitor.
  • thread: ID of the thread holding the bias lock.
  • epoch: bias timestamp.
  • ptr_to_lock_record: Pointer to the lock record in the stack.
  • ptr_to_heavyweight_monitor: Pointer to monitor monitor.

3. Object initialization sequence

According to the class loading process, the class initialization clinitis performed first , and then the object initialization initmethod is performed. The sequence is as follows:

  1. Parent class static variable
    Subclass static variable

  2. Parent class static code block
    Child class static code block

  3. Parent class method block
    Parent class constructor

  4. Subclass method block
    subclass constructor

3. Object access location

There are currently two mainstream ways to access:

  • Handle
    needs a separate memory from the heap as a handle pool, but the advantage is that the reference stores a stable handle address, and only the instance pointer in the handle is changed when the object is moved due to GC.
    Handle

  • Direct pointer has the
    advantage of being fast
    Direct pointer access

From this we know what the objects referenced in the virtual machine stack (local variable table in the stack frame) refer to in GC Roots.

Conclusion

This article sorts out the general process of object creation, which is of great help to understanding the virtual machine.

Guess you like

Origin blog.csdn.net/u014099894/article/details/105968386