JVM runtime data area-heap (object allocation process)

Heap-object allocation process

concept

Allocating memory for new objects is a very rigorous and complicated task. JVM designers not only need to consider how and where to allocate memory, but also because the memory allocation algorithm is closely related to the memory recovery algorithm, so you also need to consider GC Whether memory fragmentation will be generated in the memory space after memory reclamation is performed.

The following points are explained:

  • The new object is first placed in the Eden Park, this area has a size limit;
  • When the space in the Garden of Eden is full, the program needs to create objects again. The garbage collector of the JVM performs MinorGC on the Garden of Eden, destroys the objects in the Garden of Eden that are no longer referenced by other objects, and then loads new ones. Place the subject in the Eden Park;
  • Then move the remaining objects in the Garden of Eden to Survivor Zone 0;
  • If garbage collection is triggered again, the ones that survived last time will be placed in survivor 0 area, if not collected, they will be placed in survivor 1 area (area 0 and area 1 are swapped for each other);
  • If it goes through garbage collection again, it will be put back into the survivor 0 area at this time, and then go to the survivor 1 area.
  • When can I go to the retirement area? You can set the number of times. The default is 15 times;
  • In the retirement area, it is relatively leisurely. When the old-age area memory is insufficient, GC is triggered again: Major GC to clean up the old-age area memory;
  • If after Major GC is executed in the elderly care area, it is found that the object still cannot be saved, an OOM exception will occur.

The parameter (number of times) can be set: -Xx:MaxTenuringThreshold=N for setting.

Graphical process

  1. The objects we create are generally stored in the Eden area. When the Eden area is full, the GC operation will be triggered, which is generally called the YGC / Minor GC operation;
    Insert picture description here

  2. When we perform a garbage collection, the red ones will be recycled, and the green ones will be occupied and stored in the S0 (Survivor From) area. At the same time, an age counter is set for each object, which is 1 after one collection;

  3. At the same time, the Eden area continues to store objects. When the Eden area is full again, it will trigger a MinorGC operation. At this time, the GC will collect the objects in Eden and Survivor From once, and put the surviving objects in the Survivor To area. At the same time let age + 1;
    Insert picture description here

  4. We continue to perform object generation and garbage collection. When the age of the object in Survivor reaches 15, a promotion operation will be triggered, that is, the object in the young generation will be promoted to the old generation;
    Insert picture description here
    after the survival area is full?

  • Pay special attention to that MinorGC will only be triggered when the Eden area is full, and MinorGC operation will not be triggered when the survivor area is full;
  • If the Survivor area is full, some special rules will be triggered, that is, it may be promoted directly to the old generation.

Example: Taking the military as an example, the promotion of a normal person may be: recruit -> squad leader -> platoon leader -> company commander.

But it is also possible that some people have made a very big contribution directly from recruits -> platoon leader.

The special case
Insert picture description here
code of object allocation demonstrates the process of object allocation

Sample program: constantly create large objects and add them to the list:

public class HeapInstanceTest {
    
    
    byte [] buffer = new byte[new Random().nextInt(1024 * 200)];
    public static void main(String[] args) throws InterruptedException {
    
    
        ArrayList<HeapInstanceTest> list = new ArrayList<>();
        while (true) {
    
    
            list.add(new HeapInstanceTest());
            Thread.sleep(10);
        }
    }
}

Then set the JVM parameters:

-Xms600m -Xmx600m

Insert picture description here
Then open the VisualVM tool and execute the above code to dynamically view through VisualGC:
Insert picture description here
Finally, when the old and new generations are full, OOM appears.

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at com.heu.heap.HeapInstanceTest.<init>(HeapInstanceTest.java:13)
	at com.heu.heap.HeapInstanceTest.main(HeapInstanceTest.java:17)

to sum up

  • Summary for the survivors s0, s1 area: there is exchange after copying, and whoever is empty is to (s0, s1 are not fixed);
  • Regarding garbage collection: it is frequently collected in the newborn area, rarely collected in the old generation, and almost not collected in the permanent generation and metaspace;
  • The purpose of the new generation of replication algorithms: to reduce internal fragmentation.

Minor GC,MajorGC、Full GC

  • Minor GC: the new generation of GC

  • Major GC: GC of the old age

  • Full GC: whole heap collection, garbage collection collecting the entire Java heap and method area

  • We all know that a part of JVM tuning is garbage collection. We need to avoid garbage collection as much as possible, because in the process of garbage collection, STW (stop the word) problems are prone to occur, and Major GC and Full GC The time for STW to appear is more than 10 times that of Minor GC.

  • When JVM is performing GC, it does not always reclaim the above three memory areas together. Most of the time, the reclaiming refers to the new generation. For the implementation of Hotspot VM, the GC in it is divided into two types according to the recovery area: one is partial collection (Partial GC) and the other is full collection (FullGC).

Partial collection: Garbage collection is not a complete collection of the entire Java heap. Which is divided into:

  • The young generation collection (MinorGC/YoungGC): only the young generation of garbage collection.
  • Old generation collection (MajorGC/o1dGC): just garbage collection in the old generation.
    -Currently, only CMSGC has the behavior of collecting old generations separately;-Note
    that in many cases Major GC will be confused with Full GC, and it is necessary to specifically distinguish whether it is old generation collection or whole heap collection.
  • Mixed collection (MixedGC): Collect garbage collection of the entire young generation and part of the old generation.
    -Currently, only G1 GC will have this behavior.

Whole heap collection (FullGC): Collect the garbage collection of the entire java heap and method area.

Minor GC

  • When the young generation space is insufficient, MinorGC will be triggered. The young generation full here refers to the Eden generation full, and the Survivor full will not trigger a GC (each time the Minor GC will clean up the memory of the young generation);
  • Because most Java objects have Chaosheng evening off feature, so Minor GC very frequently, usually recover relatively fast speed;
  • Minor GC will trigger STW (stop the word), suspend the threads of other users, and wait until the garbage collection is over before the user threads resume running.
    Insert picture description here

Major GC

Majoy GC refers to the GC that occurred in the old age. When the object disappears from the old age, it is said that "Major Gc" or "Full GC" has occurred.

  • The emergence of Major GC is often accompanied by at least one Minor GC (but not absolute, there is a direct Major GC strategy selection process in the collection strategy of the Paralle1 Scavenge collector), that is, when the space of the old generation is insufficient, it will Try to trigger Minor GC first. If there is not enough space afterwards, a Major GC will be triggered;
  • The speed of Major GC is generally more than 10 times slower than that of MinorGc, and the time of STW is longer. If the memory is not enough after Major GC, it will be reported as OOM.

Full GC

There are five situations that trigger the execution of Full GC:

  1. When calling System.gc(), the system recommends to execute Full GC, but it is not necessarily executed;
  2. Insufficient space in the old age;
  3. Insufficient space in the method area;
  4. The average size of the old generation after passing the Minor GC is greater than the available memory of the old generation;
  5. When copying from Eden area, survivor spacee (From Space) area to survivor spacel (To Space) area, if the size of the object is larger than the available memory of To Space, then the object will be transferred to the old age, and the available memory of the old age is less than the size of the object (That is, the memory size of the young generation and the old generation cannot fit the object).

Note: Full GC should be avoided as much as possible during development or tuning. This way the temporary time will be shorter.

GC example

Write an OOM exception, constantly creating string examples:

public class GCTest {
    
    
    public static void main(String[] args) {
    
    
        int i = 0;
        try {
    
    
            List<String> list = new ArrayList<>();
            String a = "mogu blog";
            while(true) {
    
    
                list.add(a);
                a = a + a;
                i++;
            }
        }catch (Exception e) {
    
    
            e.getStackTrace();
        }
    }
}

Set the JVM startup parameters:

-Xms10m -Xmx10m -XX:+PrintGCDetails

Printed log:

[GC (Allocation Failure) [PSYoungGen: 2038K->500K(2560K)] 2038K->797K(9728K), 0.3532002 secs] [Times: user=0.01 sys=0.00, real=0.36 secs] 
[GC (Allocation Failure) [PSYoungGen: 2108K->480K(2560K)] 2405K->1565K(9728K), 0.0014069 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (Ergonomics) [PSYoungGen: 2288K->0K(2560K)] [ParOldGen: 6845K->5281K(7168K)] 9133K->5281K(9728K), [Metaspace: 3482K->3482K(1056768K)], 0.0058675 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
[GC (Allocation Failure) [PSYoungGen: 0K->0K(2560K)] 5281K->5281K(9728K), 0.0002857 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (Allocation Failure) [PSYoungGen: 0K->0K(2560K)] [ParOldGen: 5281K->5263K(7168K)] 5281K->5263K(9728K), [Metaspace: 3482K->3482K(1056768K)], 0.0058564 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
Heap
 PSYoungGen      total 2560K, used 60K [0x00000000ffd00000, 0x0000000100000000, 0x0000000100000000)
  eden space 2048K, 2% used [0x00000000ffd00000,0x00000000ffd0f138,0x00000000fff00000)
  from space 512K, 0% used [0x00000000fff00000,0x00000000fff00000,0x00000000fff80000)
  to   space 512K, 0% used [0x00000000fff80000,0x00000000fff80000,0x0000000100000000)
 ParOldGen       total 7168K, used 5263K [0x00000000ff600000, 0x00000000ffd00000, 0x00000000ffd00000)
  object space 7168K, 73% used [0x00000000ff600000,0x00000000ffb23cf0,0x00000000ffd00000)
 Metaspace       used 3514K, capacity 4498K, committed 4864K, reserved 1056768K
  class space    used 388K, capacity 390K, committed 512K, reserved 1048576K
  
  Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at java.util.Arrays.copyOfRange(Arrays.java:3664)
	at java.lang.String.<init>(String.java:207)
	at java.lang.StringBuilder.toString(StringBuilder.java:407)
	at com.heu.heap.GCTest.main(GCTest.java:20)
[GC (Allocation Failure) [PSYoungGen: 2038K->500K(2560K)] 2038K->797K(9728K), 0.3532002 secs] 
  • [PSYoungGen: 2038K->500K(2560K)]: The total space of the young generation is 2560K, currently occupying 2038K, and the remaining 500K after garbage collection;
  • 2038K->797K(9728K): The total heap memory space is 9728K, which currently occupies 2038K, and 797K remains after garbage collection.

When the OOM is triggered, a Full GC must be performed, because the OOM exception will only be exploded when the space in the old generation is insufficient.

Heap space generation idea

Why split the Java heap into generations? Doesn't it work properly regardless of generations?

After research, different objects have different life cycles. 70%-99% of objects are temporary objects.

  • Cenozoic: It consists of Eden and two survivors of the same size (also called from/to or s0/s1), and to is always empty.
  • Old generation: Store the objects that survived many GCs in the new generation.

In fact, it is completely possible to not split the generations, the only reason for generations is to optimize the GC performance.

  • If there is no generation, then all the objects are in the same place, it is like shutting all the people in a school in a classroom. During the GC, it is necessary to find out which objects are useless, so that all areas of the heap will be scanned. (Low performance)
  • Many objects live and die. If you are generating generations, put the newly created object in a certain place. When GC, first reclaim the area where the "live and die" objects are stored, so that it will be free. Out a lot of space. (More recycling of young generations and less recycling of old generations will improve performance a lot)

Object memory allocation strategy

  1. If the object was born in the Eden area and survived the first Minor GC, and can be accommodated by Survivor, it will be moved to the Survivor space, and the age of the object will be set to 1.
  2. Each time an object survives a Minor GC in the Survivor area, its age increases by 1 year. When its age increases to a certain level (the default is 15 years old, in fact, each JVM and each GC is different), it will be Promoted to the old age.
  3. The age threshold for the object to be promoted to the old age can be set by the option **-XX:MaxTenuringThreshold**.

The principles of object allocation for different age groups are as follows:

  1. Priority allocation to Eden: Longer strings or arrays in development will directly exist in the old age, but because the newly created objects are all day and night, this large object may also be recycled soon, but it is triggered by the old age Major GC has fewer times than Minor GC, so it may be slower to collect.
  2. Large objects are directly allocated to the old generation: try to avoid too many large objects in the program.
  3. Long-lived objects are allocated to the old generation.
  4. Dynamic object age judgment: If the sum of the size of all objects of the same age in the Survivor area is greater than half of the Survivor space, objects with an age greater than or equal to this age can directly enter the old age without waiting for the age required in MaxTenuringThreshold.
  5. Space allocation guarantee: -XX:HandlePromotionFailure.

Guess you like

Origin blog.csdn.net/qq_33626996/article/details/113954578