CMS

Concurrent Mark Sweep CMS used in the old days collections were generally triggered as FGC

Use -xx :+UseConcMarkSweepGC to use the CMS old garbage collector. By default, ParNew is used as the new garbage collector. ParNew is similar to Serial

CMS also adopts the three-color marking algorithm to mark and process the data. CMS uses the way of mark clearing to clean up garbage and CMS functions in the old garbage recycling

Concurrent garbage collector step

A concurrent collection cycle typically consists of the following steps:

  1. Suspend all application thread threads (STW), determine the set of layer 1 root reachable objects, and resume all application threads
  2. All sets of root-reachable objects are traced concurrently while the application thread executes
  3. Use a single-thread trace record to trace object references modified by concurrent application threads from the previous step
  4. Pause the application thread (STW) to re-mark portions of the root and object graph that may have changed since the last check
  5. Clean up all unmarked garbage data concurrently
  6. Resize the heap and prepare supporting data structures for the next collection cycle

InitMark

Initial marking stage

Execution of InitMark triggers a safePoint (STW) pause for all worker threads

The gray part in the figure above is the first layer root reachable object marked in the initial marking stage

Concurrent Mark

Concurrent marking phase

The worker thread of the program runs at the same time as the GC thread

The concurrent tag will go from the gray part of the tag in the initial stage to look for the reference to this area as the concurrent tag because it is usually the most time-consuming time to tag all the useful objects in memory so the CMS uses this area to reduce STW pauses and the concurrent tag will not generate STW pauses

The leakage

CMS uses incremental write barrier to solve the problem of missing marks

Final Mark

The final marking is commonly called Remark re-marking. Re-marking is the re-marking of the data missing from the concurrent marking. During the final marking, STW will be generated and all program threads will be suspended

For example, the data that was missing before has C that has been grayed out by the incremental write barrier

So finally mark what’s done and rescan the objects referenced by D and finally scan D and C and A2

The STW takes a relatively small amount of time to generate because the most time-consuming part of the GC marking process has already been done through the concurrent marking, so only objects changed during the concurrent marking process need to be scanned during this scan and the STW time is relatively short

Concurrent Clear

In the concurrent cleanup process, the previous step has separated garbage data from non-garbage data by tricolor markers. The concurrent cleanup is mainly to collect white garbage data. This step does not generate STW

Cleanup will collect the garbage object with the dotted line B

Floating Garbage

Floating garbage because concurrent cleanup is adopted during cleanup, new garbage may be generated during cleanup. In this case, new garbage is called floating garbage, which can only be removed after the next GC

Problems with CMS

Memory fragments

Because the CMS uses the token clearing method, there will be a lot of memory fragmentation, The author also wrote before with the method of tag removal is the need to maintain a free list to allocate objects Once the final memory cannot add new data (here refers to the memory of continuous space is not enough to put new objects) CMS will use Serial Old Serial garbage collector cleaning and finishing Old s rubbish

The Serial Old garbage collector is a single-thread garbage collector, so once the CMS adopts the Serial Old garbage collector, then the final STW time may not be predictable, single-thread Serial garbage collector and garbage collector is only suitable for a few meters of memory size. If you use Serial Old memory for a few hours or more, the result will be disastrous

Floating garbage

As mentioned above, CMS uses incremental write barriers. Incremental write barriers only record newly added references but not deleted references. For example, when a GCRoots reference is deleted during the concurrent marking phase, Even if there is relabeling but a reference is not deleted at the time of relabeling, of course garbage generated again during the concurrent cleanup phase is floating garbage

As the author mentioned before, the gray object D deletes the reference to the white object E, while the black object C adds the reference to the white object E. CMS adopts incremental write barrier, and records the reference from object C to object E to solve the problem of missing marks. However, it is not recorded that GCRoots deleted a reference to object B and thus failed to resolve the problem

CMS optimization

Generally, the problem of CMS is optimized to generate memory fragmentation, which eventually leads to the compression of Serial Old. The optimization method is generally to deal with the Old garbage collection in advance to avoid memory fragmentation as much as possible. Java has never made CMS garbage collector the default garbage collector since the creation of CMS

Common CMS tuning parameters

parameter describe advice
-XX:CMSInitiatingOccupancyFraction The default value is 68%. CMS collection is triggered when the old age reaches 68% This can be determined according to the actual business scenario. However, this value should not be too small or it will trigger the GC of CMS frequently. The CMS also has two periods in which STW will be generated
-XX:UseCMSInitiatingOccupancyOnly Whether CMSInitiatingOccupancyFraction values have been used as a trigger condition Just using the set CMSInitiatingOccupancyFraction, if you do not specify a CMS follow-up will automatically adjust
-XX:CMSScavengeBeforeRemark Whether to perform YGC once when the CMS triggers the default is Flase Adjust according to the actual situation
-XX:+CMSIncrementalMode Start incremental mode
-XX:CMSFullGCsBeforeCompaction How many FGC times does it take to compress old memory the default value is 0 The main purpose of this is to prevent memory fragmentation from eventually triggering the entire old collation

Promotion Failed

Promotion failed generally refers to the failure of promotion from the young generation to the old generation, generally due to memory fragmentation resulting in insufficient continuous space to put down new object data

Serial Old is a single-thread garbage collector that uses a tag collation algorithm, and STW times are very long

There are several ways to solve this problem

  1. Boost memory but preferably not more than 32GB (HotSpot will compress Pointers below 32GB)
  2. Perform CMS GC ahead of time
  3. FGC is executed during program idle time by scriptingjmap -histo:live
  4. Set toUseCMSCompactAtFullCollection,CMSFullGCsBeforeCompactionCompression occurs when CMS is executed
  5. Switch garbage collector to G1

Concurrent Mode Failure

CMS generates floating garbage. The CMS garbage collector uses one or more garbage collector threads running at the same time as the application threads to complete its collection before the tendery generation becomes full. If the tendery space cannot be collected immediately while concurrently cleaning up (floating garbage), And at the same time, the program thread generates a large amount of data, so that the old age is filled again before the cleaning is completed, that is, the garbage data can not be recycled before the old age is filled. Concurrent Mode Failure is thrown. Concurrent Mode Failure occurs

The solution Also trigger CMS recovery threshold in advance By modifying the lower CMSInitiatingOccupancyFraction values But also cannot too low, Too low will result in frequent FGC comparison and CMS will still have 2 STW. The time of the second STW will also be time-consuming under certain conditions. Generally, it is fine tuning and pressure measurement to see the frequency of FGC recovery and the size of the old age

CMS is abandoned

Because of the shortcomings of CMS and its own mechanism, the JVM reimplemented the G1 garbage collector to replace CMS garbage collector, completely removing CMS in JDK14, the first garbage collector that was completely removed by the JVM, which I will cover in more detail in G1

Excessive GC time and OutOfMemoryError

OutOfMemoryError throws an if more than 98% of the total time is spent in garbage collection and less than 2% of the heap is collected. This feature is designed to prevent an application from running for a long time and making little or no progress because the heap is too small. If necessary, you can disable this feature by adding the option -xx: -usegCoverheadLimit to the command line.