CMS

Although the CMS collector uses concurrent collection (non-exclusive), it still performs a stop-the-world mechanism to suspend the worker threads in the program during its initialization and re-marking phases, but not for very long. Thus, none of the current garbage collectors need to be stop-the-world free, but only pause as short as possible.

Because the most time-consuming concurrent marking and concurrent cleanup phases do not require pauses, the overall collection is low-pause.

** Since the user threads are not interrupted during the garbage collection phase, you should also ensure that the application user threads have enough memory available during the CMS collection process. Therefore, the CMS collector does not wait until the old age is almost completely filled, as other collectors do. Instead, the CMS collector starts collecting when the heap memory usage reaches a certain threshold to ensure that the application still has enough space to run while the CMS is working.

If the CMS is running without enough memory to meet the program’s requirements, a “Concurrent Mode Failure” occurs, at which point the virtual machine starts a fallback: the Serial old collector is temporarily enabled to restart the old garbage collection, resulting in long pauses. **

One might think that since Mark Sweep causes memory fragmentation, why not change the algorithm to Mark Compact?

Because when concurrent cleanup is done, how do you use the memory used by the user thread? To ensure that the user thread can continue executing, the resource on which it is running is not affected. The Mark Compact is better suited for “Stop the World” scenarios.

G1 Garbage First

Why is it called Garbage First (G1)?

  • Because G1 is a parallel collector, it divides heap memory into a number of unrelated regions (physically discontinuous). Use different regions to represent Eden, Survivor 0, Survivor 1, old age, and so on.
  • The G1 GC systematically avoids region-wide garbage collection across the entire Java heap.G1 tracks the value of the garbage heap in each Region(the size of the space acquired by the collection and the time required for the collection), maintain one in the backgroundPriority listAccording to the allowed collection time, the Region with the highest value is reclaimed first.
  • Since this approach focuses on regions where the most Garbage is collected, we gave G1 a name: Garbage First.
  • G1 (garbage-First) is a Garbage collector for server-side applicationsFor machines equipped with multi-core CPU and large memory capacity, while meeting GC pause times with high probability, it also has high throughput performance characteristics.
  • In JDK1.7 version officially enabled, remove the logo of Experimental, isDefault garbage collector after JDK9, replacing the CMS collector and the Parallel + Parallel old combination. Is officially referred to by Oracle as”Full-featured garbage collector
  • Meanwhile, CMS has been marked as deprecated in JDK9.It is not yet the default garbage collector in JDK8 and needs to be enabled using -xx :+UseG1GC.

G1 features:

  1. Parallelism and concurrency
  • Parallelism: G1 can have multiple GC threads working at the same time during collection, effectively leveraging multi-core computing power. At this point the user thread is STW
  • Concurrency: G1 has the ability to alternate execution with the application, so that some work can be performed at the same time as the application, so that, generally speaking, the application does not completely block during the entire reclamation phase
  1. Generational collection
  • In terms of generation, G1 is still a generational garbage collector. It differentiates the young generation from the old generation, and the young generation still has Eden and Survivor zones. However, from the structure of the heap, it does not require the whole Eden area, the young generation or the old generation to be continuous, nor does it insist on fixed size and fixed quantity.
  • The heap space is divided into regions, which containlogicallyThe younger generation and the older generation.
  • Unlike previous types of recyclers, it alsoTake care of the younger generation and the older generation. Compare other recyclers, either working in the younger generation or working in the older generation;
  1. Spatial integration
  • CMS: “mark-clean” algorithm, memory fragmentation, defragmentation after several GC
  • The G1 divides memory into regions.Memory reclamation is based on region. It’s a replication algorithm between regions, but it’s actually a mark-compact algorithm as a whole,Both algorithms can avoid memory fragmentation. This feature helps programs run for a long time and allocate large objects without triggering the next GC prematurely because contiguity memory space cannot be found. This is especially true when the Java heap is very large.
  1. Predictable pause time model (i.e., soft real-time soft real-time)
  • This is another big advantage the G1 has over CMS, in addition to its pursuit of low pausesAbility to model predictable pause timesAllows the user to explicitly specify that no more than N milliseconds should be spent on garbage collection within a time segment of M milliseconds in length.
  • Due to partitioning, G1 can select only part of the region for memory reclamation, which reduces the scope of reclamation, so that the occurrence of global pause can be well controlled.
  • G1 tracks garbage accumulation in each Regionvalue(the size of the space acquired by the collection and the time required for the collection), maintain one in the backgroundPriority listAccording to the allowable collection time,Preferentially reclaim the Region with the highest value. The G1 collector is guaranteed to achieve the highest possible collection efficiency in a limited time.
  • G1 is not necessarily as good at delaying pauses as CMS GC is at best, but much better at worst.

Comparison between CMS and G1:

Compared to CMS, G1 does not have a comprehensive, overwhelming advantage. For example, G1 has a higher garbage collection Footprint and overload than CMS during user program execution. Empirically, CMS is more likely to outperform G1 in small memory applications, while G1 is more likely to outperform G1 in large memory applications. The balance point is between 6-8GB.

Parameter Settings:

  • -xx :+UseG1GC specifies the use of the G1 collector.
  • -xx :G1HeapRegionSize Sets the size of each Region. The value is a power of 2, ranging from 1MB to 32MB, and the goal is to partition about 2048 regions based on the minimum Java heap size. The default is 1/2000 of the heap.
  • -xx :MaxGCPauseMillis sets the maximum GC pause time metric that the JVM will try to achieve, but is not guaranteed to achieve. The default value is 200ms
  • -xx :ParallelGCThread Sets the value of the number of STW worker threads. The maximum value is 8
  • -xx :ConcGCThreads Sets the number of concurrent threads to be tagged. Set n to about 1/4 of the number of parallel garbage collection threads (ParallelGCThreads).
  • – XX: InitiatingHeapOccupancyPercent set trigger a concurrent GC cycle Java heap usage rate threshold value. If this value is exceeded, GC is triggered. The default value is 45.

G1 Application Scenario

  • Server – oriented applications for machines with large memory and multiple processors. (No surprise in a normal size heap)

  • The most important applications are applications that require low GC latency and have a large heap of solutions;

  • For example, when the heap size is about 6GB or larger, predictable pause times can be less than 0.5 seconds; G1 ensures that each GC pause is not too long by incrementally cleaning only some regions at a time, not all of them.

  • To replace the CMS collector in JDK1.5; G1 may be better than CMS when:

    • More than 50% of the Java heap is occupied by active data;
    • The frequency of object assignment or chronological lifting varies greatly;
    • GC pauses are too long (longer than 0.5 to 1 second).
  • In addition to G1, other garbage collectors use a built-in JVM thread to perform multi-threaded GC operations. G1 GC can use application threads to perform background GC operations. When the JVM’s GC thread is slow, the application thread is called to help speed up the garbage collection process.

Partition Region- Divide into parts

When using the G1 collector, it divides the entire Java heap into approximately 2048 independent regions of the same size, each Region size depending on the actual size of the heap, and the overall Region size is controlled between 1MB and 32MB to the NTH power of 2. That’s 1MB, 2MB, 4MB, 8MB, 16MB, 32MB. -xx :G1HeapRegionSize Can be set. All regions are the same size and do not change during the lifetime of the JVM.

Although the concept of Cenozoic and oldyn is still retained, Cenozoic and oldyn are no longer physically separated; they are collections of parts of regions (which do not need to be continuous). Dynamic Region allocation is used to achieve logical continuity.

A region may belong to Eden, Survivor, or 0LD /Tenured memory regions. However, a region can belong to only one role. In the figure, E indicates that the region belongs to Eden memory region, S indicates that the region belongs to Survivor memory region, and 0 indicates that the region belongs to old memory region. Blank Spaces in the figure represent unused memory space. The G1 garbage collector also adds a new memory region called the Humongous memory region, shown in block H. It is used to store large objects. If the number of regions exceeds 1.5, the objects are placed in region H

The reason for setting H:

Large objects in the heap are directly assigned to the old age by default, but if it is a short-lived large object, this can have a negative impact on the garbage collector. To solve this problem, G1 has a Humongous section, which is dedicated to large objects. If an H block does not fit a large object, G1 looks for contiguous H blocks to store. Sometimes you have to start the Full GC in order to find consecutive H regions. Most of G1’s behavior treats the H region as part of the old age.

Remembered Set

A Region cannot be isolated. Objects in a Region can be referenced by objects in any Region. Do YOU need to scan the entire Java heap to determine whether an object is alive? In other generational collectors, the problem is that (more notably, G1) collecting the new generation also has to scan the old generation, which reduces the efficiency of the Minor GC;

Memory set and card table

I always thought that memory set and card table are two things, and each Region has a memory set (RSet) and card table. Then AFTER asking Daniel, I realized that RSet is actually the realization of card table, card table is an array, and RSet is a HashTable. In the old days of a Region, you don’t need to consider rsets. You just need to remember that there is a card table (array). The new generation of regions has an RSet (or HashTable).

In the old era, regions are evenly divided and all regions are recorded in the card table. The RSet of the new generation is HashTable. The key refers to the initial memory address of the Region of the new generation, which is also the initial memory address of the Region of the old age. The value of the array is the index of the card table in the old age, that is, the element number of the first card

In the RSet of the new generation, key is A and value is A and B (indicating the index and element position of the card table). The old age with the initial address of B refers to an object of the Cenozoic era, which is also recorded in the Cenozoic RSet ————————————————

Solutions:

  • For both G1 and other generational collectors, the JVM uses Remembered Set to avoid global scans:
  • Each Region has a Remembered Set.
  • Each time a Reference data Write operation is performed, a Write Barrier operation is generated. Then check whether the Reference to be written refers to an object in a different Region from the Reference type data (other collectors: check whether old objects refer to new ones).
  • If not, the references of other regions are recorded in the Remembered Set of the Region where the references point to the object through CardTable.
  • When garbage collection is performed, add the enumeration scope of the GC root to Remembered Set. You can guarantee that no global scan will be done, and there will be no omissions.

The main part of the garbage recovery process

  • Young GC
  • Concurrent Marking in the old days
  • Mixed GC
  • Single-threaded, exclusive, high-intensity Full GC will continue to exist if needed. It provides a fail-safe mechanism against GC evaluation failures, namely strong collection. (Optional)

  1. The application allocates memory and starts the young generation reclamation process when the young generation’s Eden area is exhausted. G1’s young generation collection phase is oneParallel, exclusive collector. During the young generation collection period, the G1 GC suspends all application threads and starts multithreading to perform the young generation collection. Then move the surviving object from the young generation to the Survivor or the old, or possibly both.
  2. Starts when heap memory usage reaches a certain value (45% by default)The old days of concurrent marking procedures.
  3. Start as soon as the mark is finishedMixed recovery process. For a mixed payback period, the G1 GC moves live objects from the old period to the free period, which becomes part of the old period. Unlike the younger generation, the G1 collector of the older generation is different from other GCS,G1’s vintage collector does not require the entire vintage to be recycled, but only scans/reclaims a small number of vintage regions at a time. At the same time, the old Region is reclaimed along with the young generation.Start four or five mixed collections after marking is complete.

Young GC process

  • When JVM starts, G1 prepares Eden area first, and the program continuously creates objects to Eden area during the running process. When Eden space runs out, G1 will start a young generation garbage collection process.
  • Young generation garbage collection will only collect Eden and Survivor areas.
  • In YGC, G1 stops The execution of The application stop-the-world first and creates a Collection Set, which refers to The Collection of memory segments that need to be reclaimed. The Collection in The young generation reclamation process contains all memory segments in The Eden area and Survivor area of The young generation.

Detailed stages:

  1. Scan root

The root refers to the object to which the static variable points, the local variable in the chain of method calls being executed, and so on. The root reference, along with the external reference to the RSet record, serves as the entry point for scanning the living object.

  1. Update the RSet

Process cards in the Dirty Card queue and update the RSet. After this phase is complete, the RSet can accurately reflect the reference of the old age to the object in the memory segment.

  1. Processing RSet

Identify the objects in Eden that are pointed to by the old objects. The objects in Eden that are pointed to are considered alive.

  1. Copy the object

At this stage, the object tree is traversed, and the surviving objects in the memory segment of Eden area will be copied to the hollow memory segment of Survivor area. If the age of surviving objects in the memory segment of Survivor area does not reach the threshold, the age will be increased by 1. When the age reaches the threshold, the surviving objects will be copied to the hollow memory segment of old area. If Survivor space is insufficient, some data in Eden space will be promoted directly to the old space.

  1. Deal with reference

Handle Soft, Weak, Phantom, Final, JNI Weak etc references. Finally, the data in Eden space is empty, GC stops working, and the objects in the target memory are continuously stored without fragmentation. Therefore, the replication process can achieve the effect of memory consolidation and reduce fragmentation.

Concurrent Marking in the old days

  1. Initial marking stage

Marks objects directly reachable from the root node. This phase is STW and triggers a young GC.

  1. Root Region Scanning

The G1 GC scans the old-age region objects that are directly reachable from the Survivor region and marks the referenced objects. This process must be completed before youngGC.

  1. Concurrent Marking

Concurrent marking (and application concurrent execution) throughout the heap may be interrupted by youngGC. During the concurrent marking phase, if all objects in a region object are found to be garbage, the region is immediately reclaimed. At the same time, the object activity (the percentage of living objects in the region) of each region is calculated during concurrent tagging.

  1. Mark again (Remark)

As the application continues, you need to fix the last marked result. Is the STW. G1 uses a faster initial snapshot algorithm than CMS: snapshot-at-the-beginning (SATB).

  1. Exclusive cleanup (STW)

Calculate the ratio of live objects and GC collection for each region and sort them to identify regions that can be mixed for collection. Set the stage for the next phase. Is the STW. This phase does not actually do garbage collection

  1. Concurrent cleanup phase

Identify and clean areas that are completely free.

Mixed GC

As more and more objects are promoted to old regions, the virtual machine fires a Mixed garbage collector, known as a Mixed GC, to avoid running out of heap memory

It is not an old GC. In addition to the entire Young Region, a portion of the old Region is reclaimed.

Note here: part of the old era, not all of it. You can select which old regions to collect, thus controlling the garbage collection time. Also note that Mixed GC is not a Fu1l GC.

  • After the concurrent marking ends, the segments that are 100% garbage in the old age are reclaimed and the segments that are partially garbage are calculated. By default, these older memory segments are collected eight times (which can be set to -xx :G1MixedGCCountTarget).
  • The Collection Set of a mixed Collection consists of one-eighth of old age segments, Eden segment, and Survivor segment. The algorithm of hybrid collection is exactly the same as the algorithm of young generation collection, but it collects more memory segments of the old generation. Please refer to the young generation recycling process above for details.
  • Since memory segments are recycled eight times by default in older generations, G1 prioritises memory segments with more garbage. The higher the percentage of garbage in memory segments, the more garbage will be collected first. There is a threshold will determine whether memory segments are recycled, – XX: G1MixedGCLiveThresholdPercent, the default is 65%, mean waste of memory block can be recycled to reach 65%. If the garbage ratio is too low, it means that there is a high percentage of live objects, which will take more time to replicate.
  • Mixed recycling does not have to be done eight times. There is a threshold -xx :G1HeapWastePercent, which defaults to 10%, meaning that 10% of the total heap memory is allowed to be wasted, meaning that if the percentage of garbage that can be recycled is less than 10% of the heap memory, no mixed recycling is done. Because GC takes a lot of time but recycles very little memory.

Full GC(optional)

The G1 was designed to avoid Fu11 GC. But if that doesn’t work, G1 stops The application’s execution (stop-the-world) and uses a single-threaded memory reclamation algorithm for garbage collection, with poor performance and long application pauses.

There are two possible causes of G1 Fu1l GC:

  1. [Fixed] Recycle does not have enough to-space to store promoted objects
  2. Space runs out before the concurrent processing completes.

Performance tuning is a three-step process

G1 was designed to simplify JVM performance tuning in three simple steps for developers

  • Step 1: Start the G1 garbage collector
  • Step 2: Set the maximum memory for the heap
  • Step 3: Set a maximum pause time

There are three garbage collection modes available in G1: YoungGC, Mixed GC, and Fu1l GC, which are triggered under different conditions.

G1 Optimization Suggestions

  1. Young generation size
  • Avoid using options such as -xmn or -xx :NewRatio to explicitly set the young generation size

    • If the young generation size is fixed, the heap will not be able to adjust dynamically, and the set pause time will be invalid
  • Fixed the size of the young generation to override the pause time target

  1. Don’t be too strict with your pause time goals
  • The throughput goal for the G1 GC is 90% application time and 10% garbage collection time
  • When evaluating G1 GC throughput, don’t be too harsh with pause time goals. Being too stringent means you are willing to incur more garbage collection overhead, which directly affects throughput.