Step1: class loading check

When a virtual machine arrives at a new instruction, it first checks to see if the instruction’s arguments locate the symbolic reference to the class in the constant pool, and to see if the symbolic reference represents a class that has been loaded, parsed, and initialized. If not, the corresponding class loading process must be performed first.

Step2: Allocate memory

After the class load check passes, the virtual machine next allocates memory for the new objects. The size of memory required by an object is determined after the class is loaded, and the task of allocating space for an object is equivalent to dividing a certain size of memory from the Java heap. There are two types of allocation: “pointer collision” and “free list”, which allocation is determined by whether the Java heap is clean, which in turn is determined by whether the garbage collector used has collation capabilities.

There are two ways to allocate memory:

The choice between the two approaches depends on whether the Java heap memory is tidy. Whether the Java heap memory is clean depends on whether the GC collector’s algorithm is “mark-clean” or “mark-tidy” (also known as “mark-compress”). Notably, the copy-algorithm memory is clean as well

Reference:A diagram explaining pointer collisions and free lists





Memory allocation concurrency problem

There is a very important issue when creating objects, is thread safety, because in the actual development process, object creation is very frequent things, as a virtual machine, must ensure that thread safety, generally speaking, virtual machines use two ways to ensure thread safety:

CAS+ Retry on failure: CAS is an implementation of optimistic locking. Optimistic locking is when an operation is performed each time without locking, assuming no conflicts, and then retry until it succeeds if it fails because of conflicts. The CENTRAL Authentication Service (CAS) configuration fails to retry to ensure atomicity of update operations. TLAB: each thread is allocated a block of memory in Eden area in advance. When THE JVM allocates memory to objects in the thread, it first allocates memory in TLAB. When the object is larger than the remaining memory in TLAB or the memory in TLAB is exhausted, the CAS is used for memory allocation

Step3: initialize a zero value

After the memory allocation is complete, the VIRTUAL machine needs to initialize the allocated memory space to zero values (excluding the object header). This step ensures that the instance fields of the object can be used in Java code without assigning initial values, and the program can access the zero values corresponding to the data types of these fields.

Step4: set the object header

After initializing the zero value, the virtual machine sets up the object as necessary, such as which class the object is an instance of, how to find the metadata information about the class, the object’s hash code, the object’s GC generation age, and so on. This information is stored in the object header. In addition, the object header can be set differently depending on the running status of the VM, for example, whether biased locking is enabled.

Step5: Execute the < init >() method

After all the work is done, from the virtual machine’s point of view, a new object has been created, but from the Java program’s point of view, object creation has just begun, methods have not been executed, and all fields are still zero. So, in general, the new instruction is followed by the < init >() method, which initializes the object as the programmer wants it to, until a usable object is fully generated.

Two implementations of object references

Object memory layout Reference: Object memory layout



Java object structure