[JVM] Classic garbage collector

illustrate

There are many garbage collectors (Garbage Collector, GC) in Java to choose from, each collector has its unique characteristics and applicable scenarios.

image-20230909175821479

The above picture shows seven collectors that act on different generations. If there is a connection between two collectors, it means that they can be used together. The area where the collector is located in the picture means that it belongs to the new generation collection. collector or old generation collector. This article will introduce the above garbage collectors

New generation collector

Serial collector

This is a new generation garbage collector. It has the following characteristics:

  1. Single-threaded garbage collector : The Serial collector is single-threaded, which means that it only uses one thread to perform garbage collection operations. Therefore, it is not suitable for multi-core processors and is not conducive to parallel recycling.
  2. New generation collection : The Serial collector is mainly used for garbage collection in the new generation. In the new generation, it uses the copying algorithm to copy surviving objects to a clean area, and then cleans up objects that are no longer referenced. This process is executed in a single thread.
  3. Stop-the-World pause : The Serial collector needs to stop the execution of the application when performing garbage collection, which will cause the application to pause for a period of time, which is called a "Stop-the-World" pause. Because Serial is single-threaded, this pause time is relatively long.
  4. Applicable scenarios : Since the Serial collector is single-threaded, it is generally not suitable for multi-core CPUs or applications that require low latency. But it may be a suitable option in resource-constrained environments, such as mobile devices or embedded systems.

There is also a Serial Old collector for old generation collection. The following illustrates the running process of the Serial/Serial Old collector.

image-20230909181536247

In short, the Serial garbage collector is a simple garbage collector for the Java virtual machine, suitable for some resource-constrained environments or for simple testing and learning. But for applications that require high concurrency performance and low pause times, it is generally not recommended to use the Serial collector, and other garbage collectors that are more suitable for multi-core CPUs should be considered.

ParNew collector

The ParNew collector is essentially a multi-threaded parallel version of the Serial collector. In addition to using multiple threads for garbage collection at the same time, the rest of the behavior including all control parameters, object allocation rules, recycling strategies, etc. available to the Serial collector are the same as those of the Serial collector. The collectors are completely identical, and the two collectors also share a lot of code in implementation. The working process of the ParNew collector is shown in Figure 3-8.

image-20230909181907214

The ParNew collector can be simply understood as a multi-threaded Serial collector for the new generation.

Parallel Scavenge Collector

The Parallel Scavenge (parallel clearing) collector is a garbage collector of the Java virtual machine, mainly used for garbage collection of the new generation. It is designed to perform garbage collection operations in parallel on multi-core CPUs and aims to provide high-throughput garbage collection performance.

The following is important information about the Parallel Scavenge collector:

  1. Parallel garbage collection : The Parallel Scavenge collector is a multi-threaded garbage collector that allows multiple threads to perform garbage collection operations on the new generation in parallel. This can make full use of the performance of multi-core CPUs and improve recycling performance.
  2. New generation collection : Parallel Scavenge is mainly used for garbage collection of the new generation. Objects in the new generation usually have a short life cycle, so a copy algorithm is used for garbage collection, and multi-threading is used to improve recycling efficiency.
  3. High Throughput : The main goal of Parallel Scavenge is to provide high throughput, i.e. to perform as much work of the application as possible in a period of time. It usually does not pursue extremely low pause times, but optimizes throughput.
  4. Adaptive adjustment : The Parallel Scavenge collector has an adaptive adjustment function that can dynamically adjust the garbage collection strategy according to the performance requirements of the application. For example, the ratio of young and old generations can be automatically adjusted to better meet performance needs.
  5. Stop-the-World Pause : Although Parallel Scavenge supports parallel garbage collection, a short "Stop-the-World" pause is still required when garbage collection is performed to ensure consistency and safety.
  6. Applicable scenarios : Parallel Scavenge is suitable for applications that require high throughput, and is usually used for background processing tasks, data analysis and other scenarios that require large amounts of calculations. It is less suitable for applications where low pause times are important.

old generation collector

Serial Old Collector

Serial Old is the old generation version of the Serial collector. It is also a single-threaded collector and uses the mark-collation algorithm.

The working process of the Serial Old collector is as follows

image-20230909182650027

Parallel Old Collector

Parallel Old is the old generation version of the Parallel Scavenge collector, used for old generation garbage collection. It is a supplement to the Parallel Scavenge garbage collector and is designed to provide multi-threaded, parallel execution of old generation garbage collection to improve garbage collection performance.

The working process of the Parallel Old collector is shown in Figure 3-10. Parallel Scavenge and Parallel Old are generally used together and are a "throughput-first" collector.

image-20230909182954285

CMS collector

The CMS (Concurrent Mark Sweep) collector is a collector that aims to obtain the shortest collection pause time. Mainly used for garbage collection in the old generation. Its main feature is to minimize application pause time, which is especially suitable for applications that require low pause time.

The operation of CMS is divided into the following four processes:

  1. Initial mark (CMS initial mark): "Stop The World" is required. It just marks the objects that GC Roots can directly associate with. It is very fast.
  2. Concurrent mark (CMS concurrent mark): The process of traversing the entire object graph starting from the directly associated objects of GC Roots. This process takes a long time but does not require stopping the user thread, and can run concurrently with the garbage collection thread.
  3. Remark (CMS remark): "Stop The World" is required. This is to correct the mark record of the part of the object that changes due to the continued operation of the user program during concurrent marking [incremental update]
  4. Concurrent sweep (CMS concurrent sweep): Clean up and delete the dead objects judged in the marking phase. Since there is no need to move surviving objects, this phase can also be concurrent with the user thread.

Through the following figure, you can clearly see the concurrency and pause stages in the operation steps of the CMS collector.

image-20230909184051239

CMS also has some shortcomings, as follows

  • Memory fragmentation problem : CMS is a collector based on the "mark-clear" algorithm, so it will generate a lot of memory fragments. In this way, when allocating large objects, there may be enough space but it cannot find a large enough continuous space to allocate. The current object needs to trigger a Full GC in advance

  • Performance issue : Since it is always running during the concurrent marking and concurrent cleaning phases, one thread will be occupied. If the processor has only 4 processor cores, then 25% of the processor computing resources will always be occupied during the concurrent marking and concurrent cleaning phases.

  • Unable to handle floating garbage : CMS cannot handle floating garbage (Floating Garbage), that is, garbage generated after the concurrent marking phase. These garbage objects may need to wait for the next garbage collection to be cleared.

Garbage First Collector

G1 is a generational collector, but it works differently from traditional generational collectors (young and old generations). It divides the entire heap into multiple areas, and each area can belong to the new generation, old generation, or mixed area. This division allows G1 to manage memory more flexibly.

G1 divides the entire Java heap into multiple equal-sized areas. Each area can be a new generation area, an old generation area, or a mixed area. The size of each area is usually between 1MB and 32MB, and these areas constitute G1's controllable memory management unit. There is also a special type of Humongous area in Region, which is specially used to store large objects. G1 believes that as long as the size of an object exceeds half of the capacity of a Region, it can be determined as a large object.

One of the most important features of G1 is that it does not recycle all the garbage at one time, but only recycles a part of the garbage at a time. The main goal of G1 is to prioritize recycling according to the amount of garbage. G1 will select the area containing the most garbage for recycling to minimize the pause time of garbage collection. And we can specify the pause time of garbage collection. At this time, G1 will only recycle the most valuable Region within the specified time (the value is the amount of space obtained by recycling and the experience value of the time required for recycling, and then maintain a priority in the background list)

The picture below is the memory layout of G1

image-20230909192429688

image-20230909192343025

issues that need resolving

G1's idea of ​​"breaking the heap memory into parts" divides the memory into multiple Regions of different sizes. This also creates many problems that need to be solved.

  • How to solve cross-Region reference objects? : We know that to solve cross-generational references, we use memory sets to avoid scanning the entire heap as GC Roots. However, the application of memory sets on the G1 collector is actually much more complicated, because each of its Regions maintains its own memory set. The storage structure of G1's memory set is essentially a hash table. Key is the starting address of other Regions. Value is a set, and the elements stored in it are the index numbers of the card table. This "bidirectional" card table structure (the card table is "who I point to", this structure also records "who points to me") is more complex to implement than the original card table, and because the number of Regions is larger than that of the traditional collector The number of generations is obviously much larger, so the G1 collector has a higher memory footprint than other traditional garbage collectors.

  • How to ensure the accuracy of garbage collection? : The CMS collector is implemented using the incremental update algorithm, while the G1 collector is implemented through the raw snapshot (SATB) algorithm. The impact of garbage collection on user threads is also reflected in the memory allocation of newly created objects during the recycling process. If the program continues to run, new objects will continue to be created. G1 has designed two named TAMS (Top at Mark Start) pointer, divides a part of the space in the Region for new object allocation during concurrent recycling. During concurrent recycling, the address of the newly allocated object must be above the position of these two pointers. The G1 collector defaults to objects above this address being implicitly marked, that is, by default they are alive and not included in the recycling scope.

  • How to build a reliable pause prediction model? : The pause prediction model of the G1 collector is based on the theory of Decaying Average. During the garbage collection process, the G1 collector will record the recovery time of each Region and the dirty content of each Region's memory set. The cost of each measurable step, such as the number of cards, is analyzed to obtain statistical information such as average, standard deviation, and confidence. Then use this information to predict which Regions will make up the recycling collection if recycling starts now so that the highest revenue can be obtained without exceeding the expected pause time.

Operation process

If we do not calculate the actions during the running of the user thread (such as the operation of using write barriers to maintain the memory set), the operation process of the G1 collector can be roughly divided into the following four steps:

  • Initial Marking : Just mark the objects that GC Roots can directly associate with, and modify the value of the TAMS pointer, so that when the user threads run concurrently in the next stage, new objects can be correctly allocated in the available Region. This stage requires pausing the thread, but it takes a very short time, and it is completed synchronously during Minor GC, so the G1 collector does not actually have additional pauses at this stage. (STW)

  • Concurrent Marking : Perform reachability analysis on objects in the heap starting from GC Root, recursively scan the object graph in the entire heap, and find out the objects to be recycled. This stage takes a long time, but it can be concurrent with the user program. implement. After the object graph scan is completed, the objects recorded by SATB that have reference changes during concurrency must be reprocessed.

  • Final Marking : Make another short pause for the user thread to process the last few SATB records left after the concurrent phase. (STW)

  • Screening and Recycling (Live Data Counting and Evacuation) : Responsible for updating Region statistics, sorting the recycling value and cost of each Region, and formulating a recycling plan based on the pause time expected by the user. You can freely select any number of Regions to form a recycling collection. , then copy the surviving objects of the part of the Region decided to be recycled to the empty Region, and then clean up all the space of the entire old Region. The operation here involves the movement of living objects, which must suspend the user thread and be completed by multiple collector threads in parallel. (STW)

In addition to concurrent marking, the G1 collector also completely suspends user threads in other stages. The concurrency and pause stages in the operation steps of the G1 collector are as follows:

image-20230916164126393

The difference between CMS and G1

  • CMS uses a "mark-and-sweep" algorithm. G1 is based on "mark-organize" as a whole and partially uses the "mark-copy" algorithm.
  • CMS recycles all garbage at once, and the throughput is relatively low. G1 collects part of the garbage at a time, the single pause time is controllable, and the throughput is higher.
  • CMS performs garbage collection based on generations. G1 performs garbage collection based on Region.
  • CMS uses incremental updates. G1 uses the original snapshot.
  • The CMS card table is simple, with only one reference from the old generation to the new generation. The G1 card table is complex, and each Region must have one. As a result, G1's memory set (and other memory consumption) may account for 20% or more of the entire heap capacity.
  • CMS uses post-write barriers to update maintenance card tables. G1 uses write-before barriers and encounter barriers to maintain the card table.
  • There is a high probability that CMS will still perform better than G1 in small memory applications. In large memory applications, G1 can mostly play its advantages. The balance point of Java heap capacity between this advantage and disadvantage is usually between 6GB and 8GB.
  • G1 has basically replaced CMS, and CMS has been officially marked as deprecated.
    Maintain card table. G1 uses write-before barriers and encounter barriers to maintain the card table.
  • There is a high probability that CMS will still perform better than G1 in small memory applications. In large memory applications, G1 can mostly play its advantages. The balance point of Java heap capacity between this advantage and disadvantage is usually between 6GB and 8GB.
  • G1 has basically replaced CMS, and CMS has been officially marked as deprecated.

Guess you like

Origin blog.csdn.net/m0_51545690/article/details/132921293