Objects are the most common concept in Java. They are also the soul of Java. Everything in Java is an object. The JVM is the foundation of Java, and understanding how soul and foundation blend is critical to understanding Java itself.


Object creation

Objects can be created from the Java language level up with a simple new, but deeper into the JVM, it’s much more complicated.

The process of creating objects in the JVM is divided into the following 5 steps, as shown in the figure:

Class loading check

After the virtual machine gets to a new instruction, the following steps are performed:

The first step is to check whether the directive’s argument can locate the class’s symbolic reference in the constant pool.

Check whether the class represented by this symbolic reference has been loaded, parsed, or initialized.

If not, the corresponding class loading process must be performed first.

Determines the memory size required by the object.

After the class loading check passes, the next step is to allocate memory for the new object.

Allocate memory

Allocating space for an object is equivalent to partitioning, that is, allocating a chunk of free memory to an object.

Because the Java heap memory configuration is different for different JVM VMS, there will be some differences in the allocation method.

Whether the Java heap is neat or not is determined by whether the GARBAGE collector adopted by the JVM has compression

Memory space allocation mode

Pointer to the collision

The memory in the Java heap is used when it is neat (without memory fragmentation), that is, when the garbage collector has the ability to compress.

The principle is to put the used memory in a block, unused put a block, with a pointer to do the identification, allocation of the pointer to the free memory area.

The free list

The memory in the Java heap is not orderly, that is, when the garbage collector does not have compression.

The JVM maintains a list of what memory is available, finds a large enough chunk of the list to allocate to an object instance, and updates the list of records.

Both images are presented as shown in the figure below:

Memory allocation during concurrency

Object creation is very frequent, and one of the important issues when creating objects concurrently is thread-safety.

For example: the program to create object A and object B, the underlying VM to object A allocated memory, pointer and no modification, object B at the same time using the original pointer allocated memory.

JVMS generally use two methods to ensure thread-safety.

Synchronization processing: CAS

CAS is an implementation of optimistic locking.

Optimistic locking is the process of completing an operation without locking it, assuming there is no conflict, and then retrying it again if it fails because of a conflict until it succeeds.

Failure retry is configured on the CAS server to ensure atomicity of update operations on the VM.

Local thread allocation buffer: TLAB

Each thread is allocated a chunk of memory in Eden zone in advance, which is called TLAB

When the JVM allocates memory for objects in a thread, it first allocates it in TLAB

When the object is larger than the remaining memory in TLAB is insufficient or exhausted, the above CAS is used for memory allocation

More on CAS can be found in the blogger’s other post Java Concurrency/Multithreading – A RATIONALE for CAS

Initialize the zero value

After memory allocation is complete, the VM needs to initialize the allocated memory space to zero (excluding object headers).

This step ensures that the instance fields of the object can be used directly in Java code without an initial value, and that the program can access the zero value corresponding to the data type of these fields.

Set object header

The object header is the necessary setting of the object by the VIRTUAL machine

The object header holds various information about the object such as:

Which class the object is an instance of

How do I find the metadata information for a class

Object

The GC generation age of the object

Object headers can be set in different ways depending on the VM running status, for example, whether bias locking is enabled.

Execute the init method

After all this is done, a new object has been created from the virtual machine’s point of view

From a Java program’s point of view, object creation has just begun, the <init> method has not yet been executed, and all the fields are still zero.

So in general, the execution of the new instruction is followed by the <init> method, which initializes the object as the programmer intended, so that a real usable object is fully produced.

Object memory layout

In the Hotspot virtual machine, the layout of objects in memory can be divided into three areas.

Object head

Object headers are classified into two categories as described above:

Used to store the runtime data of the object itself

A type pointer is a pointer that an object points to its class metadata, which the VIRTUAL machine uses to determine which class the object is an instance of

The instance data

This part is the valid information that the object really stores, and is the content of the various types of fields defined in the program.

Alignment filling

The alignment fill is not necessarily exist, there is no practical significance, is used to fill.

Because the automatic memory management system of the Hotspot virtual machine requires that the object start address must be an integer multiple of 8 bytes, and the object size must be an integer multiple of 8 bytes.

Therefore, when the object instance data section is not aligned, it needs to be completed by alignment padding.

Object

Objects are created to work with objects, and our Java programs manipulate concrete objects on the heap using reference data on the stack.

The object access mode is determined by the VIRTUAL machine. Currently, there are two main access modes

Use the handle

The Java heap will be divided into a block of memory as the handle pool, the reference is stored in the object handle address, and the handle contains the specific address information of the object instance data and type data, as shown in the figure:

Direct Pointers

If direct pointer access is used, then the Java layout of the object must consider how to place the information about the access type data, and reference stores the direct address of the object.

The two contrast

The main benefit of using handle access is that reference stores a stable handle address. When the object is moved, only the instance data pointer in the handle changes, and reference itself does not need to be modified.

The biggest advantage of using direct pointer access is that it is fast and saves the time cost of a pointer location.

  • That’s the JVM Virtual Machine – Understanding the whole process of Allocating, Laying out, and accessing objects in the Java Heap.
  • Also welcome to exchange discussion, this article if there is not correct place, hope everyone forgive.
  • Your support is my biggest motivation, if it helps you give me a like oh ~~~