Let’s learn some questions.

  1. How is the object created?
  2. How is the object’s memory laid out?
  3. How are objects accessed?

Note: The objects discussed in this article are limited to ordinary Java objects, excluding arrays and Class objects.

Object creation

Object creation process (in order) :

  1. Check to see if symbolic references to classes can be found in the constant pool
  2. If not found, load the class (if yes, go to the next step)
  3. The virtual machine allocates memory for newborn objects
  4. All allocated memory is initialized to zero
  5. Sets the header information for the object
  6. Execution method
  7. Push object references onto the stack

The virtual machine allocates memory for newborn objects

The size of memory required by an object is fully 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 ways to allocate memory:

  1. Bump the Pointer
  2. Free List

Pointer collision:

If memory in the Java heap is perfectly neat, all used memory is placed on one side, free memory is placed on the other, and a pointer is placed in the middle as an indicator of the dividing point, then the allocated memory simply moves that pointer to the free space by an amount equal to the size of the object.

Free List:

If memory in the Java heap is not neat, used memory and free memory cross each other, that is simply no way pointer collision, the virtual machine, you must maintain a list of records on which memory blocks are available, at the time of distribution from the list to find a large enough space division to the object instance, and update the list of records.

Except how to divided space available, there is another issue to consider is the object creation in A virtual machine is very frequent behavior, even if just modify the position of A pointer is pointing to, in the case of concurrent is not thread-safe, is possible to allocate memory object A, pointer could change, Object B also uses the original pointer to allocate memory.

There are two solutions to this problem:

  1. Synchronizes actions to allocate memory space (using CAS mechanism)
  2. Thread Local Allocation Buffer (TLAB)

Synchronizes the action of allocating memory space (using CAS mechanism) :

The default mode of the VM is to configure the CENTRAL Authentication Service (CAS) server to ensure atomicity of update operations.

Thread Local Allocation Buffer (TLAB) :

The action of allocating memory in different space according to the thread, that is, each thread allocates a small chunk of memory in the Java heap, called. Whichever thread allocates memory is allocated on the TLAB of the thread, and synchronization locking is only required when the TLAB runs out and new TLabs are allocated. The -xx :+/ -usetlab parameter is used to determine whether the VM uses TLAB.

All allocated memory is initialized to zero

After memory allocation is complete, the virtual machine needs to initialize all allocated memory space to zero (excluding the object header). ** If TLAB is used, this process can also be advanced to TLAB allocation time. ** This step ensures that the instance fields of the object can be used in Java code without initial values, and the program can access the zero values corresponding to the data types of these fields.

Sets the header information for the object

Information about which class the object is an instance of, how to find 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 of the Object. The object header can be set differently depending on the VM running status, for example, whether biased locking is enabled.

The memory layout of the object

In the HotSpot virtual machine, the layout of objects stored in memory can be divided into three areas: object headers, Instance Data, and alignment Padding.

Object Header

There are two parts of information: 1. The runtime data of the object itself. Type pointer.

1. Runtime data of the object itself:

Such as HashCode, GC generation age, lock status flags, locks held by threads, bias thread IDS, bias time stamps

2. Type pointer: a pointer to an object’s class metadata that the virtual machine uses to determine which class instance the object is.

Note: If the object is a Java array, there must also be a piece of data in the object header to record the length of the array, because the virtual machine can determine the size of the Java object from the metadata information of ordinary Java objects, but not from the array metadata.

Instance Data

The instance data part is the valid information that the object actually stores, that is, the contents of the various types of fields that we define in the program code, whether inherited from a parent class or defined in a subclass, must be recorded.

By default, the VM stores the fields in reverse order based on their width. The fields with the same width are stored together.

Align Padding

Alignment padding is not necessarily there, but merely serves as a placeholder. Since the HotSpot VIRTUAL machine’s automatic memory management system requires that the object’s starting address be an integer multiple of 8 bytes, in other words, any object’s size must be an integer multiple of 8 bytes. The object header has been carefully designed to be a multiple (1 or 2) of exactly 8 bytes, so if the object instance data part is not aligned, it needs to be filled out by alignment.

3. Object access positioning

Java programs manipulate specific objects on the heap using reference data on the stack. There are two mainstream access methods:

Handle and direct pointer. HotSpot mainly uses direct Pointers for object access.

handle

If handle access is used, a block of memory may be allocated to the Java heap as a handle pool. Reference stores the handle address of the object, and the handle contains the specific address information of the instance data and type data of the object, as shown in Figure 2-2.

The biggest benefit of using handles for access is that reference stores a stable handle address and only changes the instance data pointer in the handle when the object is moved (a very common behavior in garbage collection). Reference itself does not need to be modified.

Direct Pointers

If direct pointer access is used, the memory layout of objects in the Java heap must consider how to place the information related to the access type data. The direct stored in Reference is the address of the object. If only the object itself is accessed, the overhead of an additional indirect access is not needed, as shown in Figure 2-3.

The biggest benefit of using direct Pointers for access is that it is much faster. It saves time for a pointer location, which can add up to a significant execution cost because object access is so frequent in Java.