Java Virtual Machine Tuning (9)-A new generation of garbage collection algorithms

Background :

I’ve always wanted to share the things about the java virtual machine. I have been working on it for a long time. It’s too theoretical, and I can’t write too many special things. I see that some friends have shared it very well, and it has been organized into a system, so I will reprint it. , I hope it is useful to friends, welcome to pay attention to Pharaoh's official account [Software Pharaoh], and pay attention to not getting lost.


The bottleneck of garbage collection

The traditional generational garbage collection method has reduced the burden of garbage collection to the application to a certain extent, pushing the throughput of the application to a limit. But one problem he couldn't solve was the application suspension caused by Full GC. In some application scenarios with high real-time requirements, the accumulation of requests and request failures caused by GC pauses are unacceptable. This type of application may require the return time of the request to be within a few hundred or even tens of milliseconds. If the generational garbage collection method is to achieve this target, the maximum heap setting can only be limited to a relatively small range, but this has a limit. The processing power of the application itself is also unacceptable.

The generational garbage collection method indeed also considers the real-time requirements and provides a concurrent collector, which supports the setting of the maximum pause time, but is limited by the memory partition model of the generational garbage collection, and its effect is not very ideal.

In order to meet the real-time requirements (in fact, the original design of the Java language is also on the embedded system), a new garbage collection method is ready to come out, which supports both short pause time and large memory space allocation. It can solve the problems caused by the traditional generation method.

Evolution of incremental collection

The incremental collection method can theoretically solve the problems caused by the traditional generation method. Incremental collection divides the heap space into a series of memory blocks. When using it, use a part of it first (not all of it will be used up). During garbage collection, the surviving objects in the previously used part are placed in the unused space later. In this way, the effect of collecting while using all the time can be achieved, avoiding the situation that the traditional generation method is used up and then paused.

Of course, the traditional generational collection method also provides concurrent collection, but it has a very fatal place, that is, the entire heap is used as a memory block, which will cause fragmentation on the one hand (uncompressible), and on the other The collection is the collection of the entire heap, there is no choice, and the control of the pause time is still very weak. The incremental method, through the block of memory space, can precisely solve the above problems.

Garbage Firest(G1)

The content of this part is mainly referred to here . This article is an interpretation of the G1 algorithm paper. I didn't add anything.

aims

In terms of design goals, G1 is completely prepared for large-scale applications.

Supports very large heaps

High throughput

-Supports multiple CPUs and garbage collection threads

-In the case of the main thread suspended, use parallel collection

-In the case of the main thread running, use concurrent collection

**Real-time goal: **Can be configured to take up to M milliseconds for garbage collection within N milliseconds

Of course, G1 must meet the real-time requirements. Compared with the traditional generational recovery algorithm, there will be some loss in performance.

Detailed algorithm

img

G1 can be said to learn from the strengths of others, and strive to achieve a kind of perfection. He absorbed the advantages of incremental collection and divided the entire heap into regions of equal size. Memory recovery and division are based on regions; at the same time, he also absorbed the characteristics of CMS, divided the garbage collection process into several stages, decentralized a garbage collection process; moreover, G1 also agrees with the idea of ​​generational garbage collection, It is believed that different objects have different life cycles and can be collected in different ways. Therefore, it also supports generational garbage collection. In order to achieve the predictability of the recovery time, after scanning the regions, G1 sorts the sizes of the active objects in it, and first collects those regions with small active objects to quickly reclaim the space (there are fewer active objects to be copied) , Because the active objects are small, most of them can be considered garbage, so this method is called Garbage First (G1) garbage collection algorithm, namely: garbage first collection.

Recovery steps:

Initial Marking (Initial Marking)

G1 stores two bitmaps for marking for each region, one is the previous marking bitmap and the other is the next marking bitmap. The bitmap contains the address information of a bit to point to the starting point of the object.

Before starting Initial Marking, first clear the next marking bitmap concurrently, then stop all application threads, scan and identify the objects that can be directly accessed by root in each region, and put the value of top in the region into next top at mark start (TAMS ), and then resume all application threads.

The conditions that trigger the execution of this step are:

G1 defines a threshold value of the percentage of JVM Heap size, called h, and there is another H. The value of H is (1-h) Heap Size. Currently, the value of h is fixed. Subsequent G1 may change it Changed to dynamic, dynamically adjusted according to the running status of jvm. In generation mode, G1 also defines a u and soft limit. The value of soft limit is Hu Heap Size. When the memory used in Heap exceeds the soft limit When the value is set, this step will be executed as soon as possible within the GC pause time allowed by the application after a clean up is executed;

In the pure mode, G1 combines marking and clean up to form a ring so that clean up can fully use the marking information. When clean up starts to reclaim, the regions that can bring the most memory space are first reclaimed. After multiple clean up Up, when reclaiming regions with little space, G1 reinitializes a new ring formed by marking and clean up.

Concurrent Marking

Traverse the objects previously scanned by Initial Marking to identify the active state of the underlying objects of these objects. During this period, the relationship of the objects that are concurrently modified by the application thread is recorded in the remembered set logs, and the newly created objects are put into In the address range higher than the top value, the default state of these newly created objects is active, and the top value is modified at the same time.

Final Marking Pause

When the remembered set logs of the application thread are not full, they will not be put into the filled RS buffers. In this case, the modification of the card recorded in these remebered set logs will be updated, so this step is required. The first step is to process the content of remembered set logs existing in the application thread and modify the remembered sets accordingly. This step requires the application to be suspended and run in parallel.

Live Data Counting and Cleanup (Live Data Counting and Cleanup)

It is worth noting that in G1, it does not mean that the Final Marking Pause is executed, and the Cleanup step must be executed. Because this step needs to suspend the application, in order to meet the requirements of quasi real-time, G1 needs to be based on the maximum GC specified by the user. The resulting pause time is used to reasonably plan when to execute Cleanup. In addition, there are several situations that will trigger the execution of this step:

G1 uses a copy method to collect, and must ensure that the space for each "to space" is sufficient. Therefore, the strategy adopted by G1 is to perform the Cleanup step when the used memory space reaches H;

For G1 in full-young and partially-young generational modes, there are situations that will trigger the execution of Cleanup. In full-young mode, G1 is based on the acceptable pause time of the application and the time it takes to recycle young regions. Estimate the number of sound regions. When the number of young regions allocated by the JVM reaches this value, Cleanup will be executed; in the partially-young mode, it will be executed as frequently as possible within the acceptable suspension time of the application Cleanup, and implement Cleanup of non-young regions to the maximum.

Outlook

In the future, the tuning of the JVM may require more tuning for the G1 algorithm.


For more information, please pay attention to the official account: "Software King" , pay attention to not getting lost, Software King and his IT friends, share some of their technical insights and life stories.

Insert picture description here

Guess you like

Origin blog.csdn.net/wjg8209/article/details/109096835