JVM object creation

The main process for creating JVM objects

  1. Class loading check:
    • When the virtual machine receives a new instruction, it first checks whether the object is loaded into memory. If not, the class loading process is not entered
  2. Allocate memory:
    • When the class is loaded, the amount of memory required for the class objects is determined, so the virtual machine only needs to divide a fixed-size area of the Java heap to hold the objects.
    • Memory allocation:
      • Pointer collision: Maintains a pointer in memory space, each time the pointer is moved back a distance corresponding to the size of the object. This method ensures that the memory space is organized, with used items in front of the pointer and unused items behind the pointer.
      • Free list: If the memory space is cluttered and used and unused areas are interlaced, the virtual machine maintains a free list to keep track of which areas are available. When an object is saved, a chunk of memory large enough to hold the object is found and the free list is updated.
    • Memory contention under high concurrency:
      • CAS: Uses the CAS algorithm to let thread A try to obtain the saving object. If the saving fails, thread A tries again until the saving succeeds.
      • Thread Local Allocation Buffer (TLAB) : When a Java Thread is enabled, an area of free memory is allocated to hold objects generated by the Thread. You can set the allocated area size by -xx :+UseTLAB (enabled by default) and -xx :TLABSize= 4K.
  3. Initialization:
    • Setting the allocated memory to a value of 0 (0/1 for both secondary codes) ensures that Java code can be used without an initial value.
  4. Set up theObject head:
    • After the zero value is initialized, 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 of the Object.
  5. Execute the init method:
    • Assign a value to an attribute of an object.

Object memory allocation

Object memory allocation process

Object stack allocation

We know that objects are allocated in THE heap, and when objects are not referenced, we rely on THE GC to recycle them, and when there are too many temporary objects, it puts a lot of pressure on THE GC, which can affect application performance (GC can STOP THE WORLD). To avoid this, the JVM uses escape analysis to determine whether an object is referenced outside of a method. If the object does not escape and there is enough stack frame space, the JVM stores the object in the stack frame so that when the method ends, the object is destroyed as the stack frame exits, relieving the GC. By enabling escape analysis (-xx :+DoEscapeAnalysis), escape analysis is enabled by default in JDK7

// The object does not escape
public void doSomething(a){
    Something st = new Something();
    st.setId();
    st.setThing();
    // Save the data operation
}
Copy the code
// Object escape
public Something getSomething(a){
    Something st = new Something();
    st.setId();
    st.setThing();
    return st;
}
Copy the code

Scalar replacement

When the escape analysis determines that the object is not referenced externally, the object is decomposed. Instead of being created in the stack frame, the member variables of the object are decomposed and several member variables are replaced by the member variables used in this method. When the JVM saves objects to the stack frame, there may be enough space in the stack frame, but the space is not continuous, which requires us to enable the JVM’s scalar replacement feature. Turn on the scalar substitution parameter (-xx :+EliminateAllocations), which is on by default after JDK7.

The big object

When the JVM determines a large object, it puts it directly into the old age. How to determine large objects? The JVM parameter – XX: PretenureSizeThreshold can set the thresholds of large objects. Why set large objects? Avoid performance problems associated with copying large objects during minor GC.

Object dynamic age judgment

If the object age is n1+ N2 +… +nx is 50% larger than S0/S1, then objects of age X and older are moved directly into the old age. This rule is actually to hope that those objects that are likely to be long-term survival, as early as possible into the old age. The size can be specified with -xx :TargetSurvivorRatio.

Old chronospatial allocation guarantee mechanism

Before each minor GC for the young generation, the JVM calculates the remaining free space for the old generation. If the available space is less than the sum of the size of all existing objects in the young generation (including junk objects), a “-xx: -handlePromotionFailure” parameter (jdK1.8 default) is checked to see if it is set. If this parameter is present, it looks to see if the available memory size of the old age is greater than the average size of objects that entered the old age after each previous minor GC. If the result of the previous step is less than or the previous parameter is not set, then a Full GC will be triggered, and garbage will be collected for both the old generation and the young generation. If there is still not enough space to store new objects, then “OOM” will occur. Full GC will also be triggered if the size of the remaining objects that need to be moved to the old age after the Minor gc is still larger than the available space of the old age. After full GC, if there is still no space for the remaining objects that need to be moved to the old age after the minor GC, then “OOM” will also occur.