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:
- Suspend all application thread threads (STW), determine the set of layer 1 root reachable objects, and resume all application threads
- All sets of root-reachable objects are traced concurrently while the application thread executes
- Use a single-thread trace record to trace object references modified by concurrent application threads from the previous step
- Pause the application thread (STW) to re-mark portions of the root and object graph that may have changed since the last check
- Clean up all unmarked garbage data concurrently
- 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
- Boost memory but preferably not more than 32GB (HotSpot will compress Pointers below 32GB)
- Perform CMS GC ahead of time
- FGC is executed during program idle time by scripting
jmap -histo:live
- Set to
UseCMSCompactAtFullCollection
,CMSFullGCsBeforeCompaction
Compression occurs when CMS is executed - 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.