Learn about G1 in detail, understand G1, detailed explanation of G1 garbage collector, simple tuning of G1 garbage collector

4. Learn about G1 in detail:
4.1. One: What is garbage collection
4.2. Understanding G1
4.3. G1 Yong GC
4.4. G1 Mix GC
4.5. Three-color marking algorithm
4.6. Tuning practice
5. G1 garbage collector detailed explanation
5.1. G1 garbage Collector
5.2. G1 heap memory division 5.3
. G1 running process
5.4. Three-color marking
5.4.1. Missing mark problem
5.5. Memory set and card table
5.6. Safe point and safe area
6. Simple tuning of G1 garbage collector
6.1. Heap
6.2. Parameters enabled after Java 9
6.3. GC phase of G1
6.4. Young Only Phase
6.5. Mixed gc Phase
6.6. Full gc Phase
6.7. First look at GC cycle
6.8. gc log

4. Learn more about G1:

Reposted from: https://www.cnblogs.com/lsgxeva/p/10231201.html

4.1.1: What is Garbage Collection

First of all, before understanding G1, we need to know clearly what is garbage collection? Simply put, garbage collection is to reclaim objects that are no longer used in memory.

The basic steps of garbage collection:
1. Find objects that are no longer used in memory.
2. Release the memory occupied by these objects.

1. Find objects that are no longer used in memory
So the question is, how to judge which objects are no longer used? We also have 2 methods:
A: Reference counting method
Reference counting method means that if an object is not pointed to by any reference, it can be regarded as garbage. The disadvantage of this method is that it cannot detect the existence of rings.

B: Root Search Algorithm (Accessibility Analysis Algorithm)
The basic idea of ​​the root search algorithm is to use a series of objects named "GC Roots" as the starting point, and start searching downward from these nodes. The path traveled by the search is called Reference chain (Reference Chain), when an object is connected to GC Roots without any reference chain, it proves that the object is unavailable.

Now that we know how to find garbage objects, how do we clean them up?

2. Release the memory occupied by these objects
Common methods include copying or direct cleaning, but direct cleaning will cause memory fragmentation, so the method of cleaning and compressing will come into being.

In general, there are three types of recycling algorithms.
A. Mark-Copy
It divides the available memory capacity into two pieces of equal size, and only uses one of them at a time. When this block is used up, copy the surviving object to another block, and then clean up the used memory space at one time. Its advantages are simple implementation, high efficiency, and no memory fragmentation. The downside is that it takes twice as much memory to manage.

B. Marking-Cleaning
The mark-clearing algorithm is divided into two stages: "marking" and "clearing": first mark the objects that need to be recycled, and clear the objects uniformly after the marking is completed. Its advantage is high efficiency, and its disadvantage is that it is prone to memory fragmentation.

C. Marking-cleaning
The marking operation is consistent with the "marking-cleaning" algorithm. Subsequent operations are not just cleaning up objects directly, but moving all surviving objects to one end after cleaning up useless objects, and updating the pointers that refer to their objects. Because objects are moved, it is less efficient than "mark-and-clean", but it does not cause memory fragmentation.

3. Based on generational assumptions
Since the survival time of objects can be long or short, for objects with a long survival time, reducing the number of GCs can avoid unnecessary overhead. In this way, we divide the memory into the new generation and the old generation. The new generation stores the newly created objects with a relatively short survival time.

4. History of the Java Garbage Collector

  • The first stage, Serial (serial) collector
    Before jdk1.3.1, the java virtual machine can only use the Serial collector. The Serial collector is a single-threaded collector, but its "single-threaded" meaning does not only mean that it will only use one CPU or one collection thread to complete the garbage collection work, but more importantly, it is used for garbage collection. , all other worker threads must be suspended until its collection finishes.

PS: How to open the Serial collector

-XX:+UseSerialGC
  • The second stage, Parallel (parallel) collector
    Parallel collector is also called throughput collector. Compared with Serial collector, the main advantage of Parallel is that it uses multi-threading to complete garbage cleaning, which can make full use of the characteristics of multi-core, greatly Reduce gc time.
    PS: The way to open the Parallel collector
-XX:+UseParallelGC -XX:+UseParallelOldGC
  • In the third stage, the CMS (concurrent) collector
    The CMS collector will suspend all application threads during Minor GC and perform garbage collection in a multi-threaded manner. During Full GC, the application thread is no longer suspended, but several background threads are used to periodically scan the old generation space and reclaim unused objects in time.
    PS: The way to open the CMS collector
-XX:+UseParNewGC -XX:+UseConcMarkSweepGC
  • The fourth stage, the G1 (concurrent) collector
    The G1 collector (or garbage-first collector) is designed to minimize pauses when processing very large heaps (greater than 4GB). Compared with the advantage of CMS, the generation rate of memory fragmentation is greatly reduced.

PS: The way to open the G1 collector

-XX:+UseG1GC

4.2. Understanding G1

The first paper (Appendix 1) of G1 was published in 2004, and it was only available in jdk1.7u4 in 2012. Oracle officially plans to make G1 the default garbage collector in jdk9 to replace CMS. Why does oracle strongly recommend G1? What are the advantages of G1?

First of all, the design principle of G1 is simple and feasible performance tuning.
Developers only need to declare the following parameters:

-XX:+UseG1GC -Xmx32g -XX:MaxGCPauseMillis=200

Among them, -XX:+UseG1GC is to enable the G1 garbage collector, -Xmx32g design the maximum memory of the heap memory to be 32G, and -XX:MaxGCPauseMillis=200 sets the maximum pause time of GC to 200ms. If we need to tune, in the case of a certain memory size, we only need to modify the maximum pause time.

Secondly, G1 cancels the physical space division of the new generation and the old generation.
In this way, we no longer need to set up each generation in a separate space, and we don't have to worry about whether the memory of each generation is enough.
insert image description here

Instead, the G1 algorithm divides the heap into several regions (Regions), which still belong to the generational collector. However, some of these areas include the new generation, and the garbage collection of the new generation still uses the method of suspending all application threads to copy surviving objects to the old generation or Survivor space. The old generation is also divided into many regions, and the G1 collector completes the cleanup by copying objects from one region to another. This means that during normal processing, G1 completes the heap compaction (at least part of the heap compaction), so that there will be no cms memory fragmentation problems.
insert image description here

In G1, there is also a special area called the Humongous area. If an object occupies more than 50% of the partition capacity, the G1 collector considers it a giant object. These giant objects are directly allocated in the old generation by default, but if it is a short-lived giant object, it will have a negative impact on the garbage collector. To solve this problem, G1 divides a Humongous area, which is used to store huge objects. If a huge object cannot be accommodated in one H area, then G1 will look for continuous H partitions to store it. In order to find continuous H areas, sometimes Full GC has to be started.

PS: In java 8, the persistent generation is also moved to the ordinary heap memory space and changed to metaspace.

Object Allocation Strategy
Speaking of the allocation of large objects, we have to talk about the object allocation strategy. It is divided into 3 stages:
1.TLAB (Thread Local Allocation Buffer) thread local allocation buffer.
2. Allocated in Eden district.
3. Humongous area allocation.

TLAB allocates buffers locally for threads, and its purpose is to make objects allocated as quickly as possible. If the objects are allocated in a shared space, we need to use some synchronization mechanism to manage the free space pointers in these spaces. In the Eden space, each thread has a fixed partition for allocating objects, that is, a TLAB. When objects are allocated, there is no longer any need for any synchronization between threads.

For objects that cannot be allocated in the TLAB space, the JVM will try to allocate them in the Eden space. If the Eden space cannot accommodate the object, the space can only be allocated in the old generation.

Finally, G1 provides two GC modes, Young GC and Mixed GC, both of which are Stop The World (STW). Below we will introduce these two modes separately.

4.3. G1 Yong GC

Young GC is mainly to GC the Eden area, which will be triggered when the Eden space is exhausted. In this case, the data in the Eden space is moved to the Survivor space. If the Survivor space is not enough, part of the data in the Eden space will be directly promoted to the old generation space. The data in the Survivor area is moved to the new Survivor area, and some data is also promoted to the old generation space. In the end, the data in the Eden space is empty, the GC stops working, and the application thread continues to execute.
insert image description here
insert image description here

At this time, we need to consider a problem, if only GC new generation objects, how do we find all root objects? Are all objects in the old generation roots? It will take a lot of time to scan in this way. Therefore, G1 introduced the concept of RSet. Its full name is Remembered Set, and its function is to track object references pointing to a certain heap area.
insert image description here

In CMS, there is also the concept of RSet. In the old generation, there is an area used to record references to the new generation. This is a point-out. When performing Young GC, when scanning the root, only this area needs to be scanned, instead of the entire old generation.

But in G1, point-out is not used. This is because a partition is too small and there are too many partitions. If point-out is used, it will cause a lot of scanning waste. Some partition references that do not need GC are also scanned up. So G1 uses point-in to solve it. Point-in means which partitions refer to objects in the current partition. This way, scanning only these objects as roots avoids invalid scans. Since there are multiple new generations, do we need to record references between new generations? This is unnecessary, because every GC, all young generations will be scanned, so only the references between the old generation and the new generation need to be recorded.

It should be noted that if there are many referenced objects, the evaluator needs to process each reference, and the evaluator overhead will be very large. In order to solve the problem of evaluator overhead, another concept is introduced in G1, the card table (Card Table). A Card Table logically divides a partition into continuous areas of fixed size, and each area is called a card. Cards are usually smaller, between 128 and 512 bytes. The Card Table is usually a byte array, and the space address of each partition is identified by the index of the Card (that is, the subscript of the array). By default, each card is unreferenced. When an address space is referenced, the value of the array index corresponding to this address space is marked as "0", that is, it is marked as dirty and referenced, and RSet also records the array subscript. In general, this RSet is actually a Hash Table, the Key is the starting address of other Regions, and the Value is a collection whose elements are the Index of the Card Table.

Young GC phase:

  • Phase 1: Root Scan
    Static and local objects are scanned.

  • Phase 2: Update RS
    Processing dirty card queue update RS.

  • Phase 3: Process RS
    to detect objects pointing from the young generation to the old generation.

  • Phase 4: Object copy
    Copy the surviving object to the survivor/old area.

  • Phase 5: Processing reference queues
    Soft references, weak references, and phantom reference processing.

4.4.G1 Mix GC

Mix GC not only performs normal new generation garbage collection, but also reclaims some old generation partitions marked by background scanning threads.

Its GC steps are divided into 2 steps:

  • global concurrent marking
  • Copy surviving objects (evacuation)

Before performing Mix GC, global concurrent marking (global concurrent marking) will be performed first. What is the execution process of global concurrent marking?

In G1 GC, it mainly provides marking services for Mixed GC, and is not a necessary part of a GC process. The execution process of global concurrent marking is divided into five steps:

  • Initial mark (initial mark, STW)
    In this phase, the G1 GC marks the root. This phase is closely related to regular (STW) young generation garbage collection.

  • Root region scan (root region scan)
    G1 GC scans references to the old generation in the initially marked survival area and marks the referenced objects. This phase runs concurrently with the application (non-STW), and the next STW young generation garbage collection cannot begin until this phase completes.

  • Concurrent Marking
    G1 GC looks for reachable (live) objects throughout the heap. This phase runs concurrently with the application and can be interrupted by STW young generation garbage collections.

  • Final mark (Remark, STW)
    This phase is STW recycling, helping to complete the marking cycle. The G1 GC clears the SATB buffer, keeps track of live objects that have not been accessed, and performs reference handling.

  • Cleanup (STW)
    In this final phase, the G1 GC performs the STW operations of statistics and RSet cleanup. During statistics, the G1 GC identifies regions that are completely free and regions that are eligible for mixed garbage collection. The cleanup phase is partially concurrent in resetting the free space and returning it to the free list.

4.5. Three-color marking algorithm

When it comes to concurrent marking, we have to understand the three-color marking algorithm of concurrent marking. It is a useful way of describing a tracing collector, and it can be used to deduce the correctness of the collector. First, we divide objects into three types.

  • Black: The root object, or both the object and its children are scanned.
  • Gray: The object itself is scanned, but the sub-objects within that object have not been scanned yet.
  • White: Objects that have not been scanned. After scanning all objects, the objects that are finally white are unreachable objects, that is, garbage objects

When the GC starts to scan objects, scan the objects according to the following steps: the
root object is set to black, and the child object is set to gray.
insert image description here
Continue to traverse from gray, and set the objects that have scanned sub-objects to black.
insert image description here
After traversing all reachable objects, all reachable objects become black. Unreachable objects are white and need to be cleaned up.
insert image description here

This looks nice, but if the application is running while the marking is in progress, the object's pointer may change. In this case, we will encounter a problem: the problem of object loss.

Let's look at the following situation, when the garbage collector scans the following situation: At
insert image description here
this time, the application performs the following operations:

A.c = C
B.c = null

In this way, the state diagram of the object becomes as follows:
insert image description here

At this time, when the garbage collector marks and scans again, it will look like this:
insert image description here
Obviously, C is white at this time, and it is considered to be garbage and needs to be cleaned up. Obviously, this is unreasonable. So how do we ensure that the objects marked by GC are not lost when the application is running? There are two feasible ways as follows:
1. Record the object when inserting.
2. Record the object when it is deleted.

It just so happens that this corresponds to two different implementations of CMS and G1:

Incremental update is used in CMS. As long as a reference to a white object is found to be assigned to a field of a black object in the write barrier (write barrier), then the white object will be turned gray . That is, when it is inserted, it is recorded.

In G1, the STAB (snapshot-at-the-beginning) method is used to record all objects when deleting. It has 3 steps:

1. Generate a snapshot to mark surviving objects at the start of marking.
2. Enqueue all changed objects at the time of concurrent marking (in the write barrier, all objects pointed to by old references will become non-white)

3. There may be free garbage, which will be collected next time

In this way, G1 can now know which old partitions have the most recyclable garbage. When the global concurrent marking is completed, at a certain point, Mix GC starts. These garbage collections are called "hybrid" because they not only perform normal young generation garbage collection, but also reclaim some partitions marked by the background scanning thread. The hybrid garbage collection is as shown in the figure below:
insert image description here
the hybrid GC also adopts a copy cleaning strategy. When the GC is completed, the space will be released again.
insert image description here
At this point, the hybrid GC has come to an end. In the next section, we will talk about entering the tuning practice.

</

Guess you like

Origin blog.csdn.net/toto1297488504/article/details/132435745