Object memory allocation procedure



1. Class loading

After using the new keyword, first check whether the parameter of this instruction can find the corresponding symbol reference in the constant pool. If no symbol reference is found or the corresponding class in the constant pool is not loaded, first load the class.

2. Allocate memory space

After the class is loaded, the new object will be allocated memory space. The size of the instance can be determined after the class is loaded. Allocating space for the object is equivalent to partitioning from memory

Allocation methods: pointer collision method, free list;

Pointer collisions (default to pointer collisions) : If Java memory is orderly, all used memory is stored on one side, and free memory is stored on one side with a pointer in the middle as an indicator of the dividing point, allocating memory simply moves the pointer to the free memory side by the same size as the object.

Free list: if Java memory is not neat, have used memory and unused memory cross each other, then it cannot be a pointer, the Java virtual machine maintains a list of records which blocks of memory is available, at the time of distribution from the list to find a large enough memory space allocated to the object and update the list of records.

Memory allocation concurrency problem solving:

Cas: The CAS is configured for the VM to synchronize memory space allocation to ensure atomicity of update operations.

Local Thread allocation buffering (TLAB) : The allocation of memory into different Spaces according to the threads, that is, each Java thread allocates a block of memory in memory. The -xx :+/ -usetlab parameter controls whether to enable TLAB, and -xx :TLABSize specifies the TLAB memory size.

3. Initialization

After the memory is allocated, variables allocated to the memory space need to be initialized (without setting the object header). If TLAB is set, the initialization process will be carried out in advance to TLAB.

4. Set the object header

After initialization, you need to set the header of the object, including the instance of the object, the age of the object, how to find metadata information, and the hash code of the object. An object can be divided into: object header, instance data, and alignment padding.

The object header in HotSpot consists of two main parts: Mark word (data required by the object itself to run, including hash code, generation age, lock status identification, bias thread ID, etc.), klassPointer (type pointer, pointing to the metadata information corresponding to the class in the method area, through the type pointer to determine the instance information of which class the object is).



5. Execute init

Executes the constructor of the object, setting the specified value for the object.



Object stack allocation

Objects are allocated on the heap. When objects are not referenced, the GC needs to reclaim them. If there are too many objects, the GC will be stressed and performance will be affected. To reduce temporary object allocation on pairs, Java virtual machines introduce escape analysis. The JVM uses escape analysis to determine whether an object will escape within the method. If it is determined that the object will not escape, it allocates memory on the stack and is destroyed as the stack frame exits the stack after the call, reducing the pressure on the GC.

Escape analysis: Analyzes the dynamic scope of an object. When an object is defined in a method, it may be referenced by an external method, for example, as a parameter to another method.

public User test1(){
   User user=new User();
   user.setId(1);
   user.setName("zhuge"); //TODO saves to databasereturn user;
}

public void test2(){
    User user=new User();
    user.setId(1);
    user.setName("zhuge"); //TODO saves to database}Copy the code

The User object in test1() is returned to the calling method, and the scope of the user object is not determined, so it is not assigned to the stack. In test2(), the scope of the user object is only within the method. The user object is also destroyed when the test2 method ends, so you can assign the user object to the stack. The JVM turns on the escape analysis parameter with -xx :+DoEscapeAnalysis to optimize the allocation of object memory so that it is prioritized on the stack by scalar substitution. (Escape analysis is enabled by default after JDK1.7)

Scalars and aggregate quantities: Scalars are quantities that cannot be further decomposed. JAVA’s basic data types are scalars, which correspond to aggregate quantities that can be further decomposed. JAVA objects are aggregate quantities that can be further decomposed. (Turn on scalar substitutions -xx :+EliminateAllocations)

The allocation of objects on the stack depends on escape analysis and scalar substitution.

The object is allocated in Eden

Most objects are allocated in Eden, and a Minor GC is triggered when there is not enough space in Eden.

Minor /Young GC: Refers to garbage collection in the new generation. Minor GC occurs frequently and quickly.

Major /Full GC: Garbage collection that occurred in the old days. The Major GC typically triggers garbage collection in the young generation, old generation, and method area. Major GC garbage collection is generally slower than Minor GC garbage collection.

The default Eden and Survivor ratio is 8:1:1 (JVM default enabled -xx :+UseAdaptiveSizePolicy will change the ratio, if you do not want to change the ratio, you can use -xx: -useadaptivesizePolicy)

When an object is created, it is allocated in Eden. When Eden is full, a Minor GC is triggered to collect the Eden garbage and place the surviving object into S0. The next time Eden is full, a minor GC will be triggered to reclaim Eden and S0, move the surviving objects in Eden and S0 to S1, and then empty Eden and S0. Once Eden is full, minor GC is triggered to collect Eden and S1, copy surviving objects to S0, and empty S1. The object will be placed in the old age after s0 and S1 have swapped a certain number of times.

Big object goes straight to the old age

Large object storage needs continuous memory space for storage, the JVM can through – XX: PretenureSizeThreshold can set the size of a large object, if more than set the value of the object directly into old age, not the young generation, this parameter is Serial ParNew effective under two collector. Moving large objects directly into the old age avoids frequent replication of large objects in the young generation, resulting in low efficiency.

The long-lived object enters the old age

Virtual machines use generational collection to manage memory, so memory collection must identify which objects are in the new generation and which objects are in the old generation. To do this, the JVM sets an Age for each object to identify the Age of the object.

If the object is born in Eden and survives one minor GC, and the survivor region can accept the object, the age of the object is 1. The age of the object is increased by 1 for each subsequent move from S0 to S1, and the object is moved to the old age when it is older than 15 years (CMS defaults to 6 years). The threshold at which an object is promoted to the old age is specified by -xx :MaxTenuringThreshold.

Dynamic age judgment

If the total size of a batch of objects currently in the Survivor zone exceeds 50% of the Survivor size (-xx :TargetSurvivorRatio specified), then objects that are greater than or equal to the maximum age of the batch of objects can enter the old age. For example, if there is a group of objects in the Survivor region whose age 1 + age 2 + age 3 + age N exceeds 50% of the size of the Survivor region, then objects whose age >=n will be added to the old age. The purpose of dynamic age determination is to advance objects that have survived multiple times into the old age, and winter age determination is generally done after minor GC.

Old chronospatial allocation guarantee mechanism

The young generation calculates the size of the remaining space of the old generation before allocating space. If the remaining space of the old generation is less than the sum of all objects (including garbage objects) of the young generation, check whether -xx: -handlePromotionFailure is set. To see if the size of the remaining space in the old age is greater than the average size of objects placed into the old age per minor GC. If this parameter is not set or the value of the previous step is less than, then a full GC will be triggered, and a garbage collection will be performed for the old and young generations. If the garbage collection still does not have enough space for new objects, an OOM will occur. Full GC will also trigger oom if there is still not enough space for minro’s surviving objects to be moved to the old age.



Object memory reclamation

Objects need to be marked before they can be reclaimed. JVM is mainly implemented by referrer counting method and reachability analysis method.

Reference counter method: each object has a reference counter, which is +1 when it is referenced and -1 when it is invalidated. The object can no longer be used until the reference counter is 0. Reference counter method is more efficient, but can not solve the problem of circular reference.

As shown below, two objects refer to each other except for objA and ObjB that refer to them. When objA and ObjB do not refer to two objects, they cannot be reclaimed because of mutual references between the two objects.

public class public class ReferenceCountingGc { Object instance = null; public static void main(String[] args) { ReferenceCountingGc objA = new ReferenceCountingGc(); ReferenceCountingGc objB = new ReferenceCountingGc(); objA.instance = objB; objB.instance = objA; objA = null; objB = null; }}Copy the code

Reachability analysis: Search down the referenced objects from the GC Root object as a starting point. The objects found are marked as non-garbage and the remaining unmarked objects are garbage.

Objects that can be used as GC Root: local variables on the thread stack, static variables, local variables on the local method stack.



Common reference types

Strong references: objects generated with the keyword new will not be recycled even if oom occurs.

SoftReference: an object is wrapped in the SoftReference SoftReference type. Normally, this object is not reclaimed. After GC occurs, the object is reclaimed only when there is insufficient space. Soft references can be used for caching.

WeakReference: an error is reported when the object uses WeakReference. When GC occurs, it will be directly recycled.

Virtual reference: Virtual reference is also called ghost reference. It is the weakest reference relationship and is not used in general.

How do YOU tell if a class is a useless reference class

1. All instances of this class have been collected, and there are no instances of this class in the Java heap

2. The ClassLoader that loaded the class has been reclaimed

3. The java.lang.Class object of this Class is not referenced and cannot be reflected anywhere to obtain an instance of the Class