Java GC Tutorials - Herong's Tutorial Examples - v1.12, by Herong Yang
"-XX:ConcGCThreads=3" - Old GC Concurrent Threads
This section demonstrates that the '-XX:ConcGCThreads=3' option can be used to control the number of threads used in 1 of the CMS concurrent phases: Mark phase.
In the last tutorial, we learned how to use the "-XX:ParallelGCThreads=6" JVM option to control the number threads used in Old GC parallel (stop-the-world) phases.
In this tutorial, let's try to use the "-XX:ConcGCThreads=5" JVM option to control the number threads used in Old GC concurrent phases.
herong> java -XX:+UseConcMarkSweepGC \ -Xms90m -Xmx90m -XX:NewRatio=2 -XX:SurvivorRatio=1 \ -XX:CMSInitiatingOccupancyFraction=20 \ -XX:+UseCMSInitiatingOccupancyOnly \ -XX:ParallelGCThreads=6 -XX:ConcGCThreads=5 \ -Xlog:gc*=trace \ GarbageCollection2 > output.txt herong> more output.txt GC(13) Pause Initial Mark GC(13) checkpointRootsInitialWork GC(13) eden 0x00000000fa600000-0x00000000fa700010-... GC(13) _eden_chunk_index=1, _eden_chunk_capacity=1281 GC(13) _eden_chunk_array[0]=0x00000000fa700010 GC(13) survivor 0x00000000fb000000-0x00000000fb800080-... GC(13) _survivor_chunk_index=0, _survivor_chunk_capacity=5120 GC(13) oops_do_marking_prologue GC(13) WorkerManager::add_workers() : created_workers: 6 GC(13) GC Thread: using 6 out of 6 workers ... GC(13) oops_do_marking_epilogue GC(13) checkpointRootsInitialWork 0.316ms GC(13) Pause Initial Mark 40M->40M(80M) 0.335ms GC(13) User=0.00s Sys=0.00s Real=0.00s -- Initial Mark phase, Pause -- 6 threads used as specified by -XX:ParallelGCThreads=6 GC(13) Concurrent Mark GC(13) WorkerManager::add_workers() : created_workers: 5 GC(13) CMS Thread: using 5 out of 5 workers GC(13) Using 5 workers of 5 for marking GC(13) Finished cms space scanning in 1th thread: 0.000 sec GC(13) Finished cms space scanning in 2th thread: 0.000 sec GC(13) Finished cms space scanning in 3th thread: 0.000 sec GC(13) Finished cms space scanning in 4th thread: 0.000 sec GC(13) Finished cms space scanning in 0th thread: 0.005 sec GC(13) Finished work stealing in 0th thread: 0.000 sec GC(13) Finished work stealing in 4th thread: 0.005 sec GC(13) Finished work stealing in 3th thread: 0.005 sec GC(13) Finished work stealing in 1th thread: 0.005 sec GC(13) Finished work stealing in 2th thread: 0.005 sec GC(13) Concurrent active time: 0.002ms GC(13) (CMS Concurrent Mark yielded 1 times) GC(13) Concurrent Mark 5.709ms GC(13) User=0.00s Sys=0.00s Real=0.01s -- Mark phase, Concurrent -- 5 threads used as specified by -XX:ConcGCThreads=5 GC(13) Concurrent Preclean GC(13) Preclean SoftReferences 0.065ms GC(13) Preclean WeakReferences 0.048ms GC(13) Preclean FinalReferences 0.022ms GC(13) Preclean PhantomReferences 0.036ms GC(13) Concurrent Preclean 0.438ms GC(13) User=0.00s Sys=0.00s Real=0.00s -- Preclean phase, Concurrent GC(13) Concurrent Abortable Preclean GC(13) Concurrent Abortable Preclean 16.231ms GC(13) User=0.03s Sys=0.00s Real=0.02s -- Abortable Preclean phase, Concurrent
GC(13) Pause Remark GC(13) YG occupancy: 8392 K (20480 K) GC(13) checkpointRootsFinalWork GC(13) eden 0x00000000fa600000-0x00000000fa7321b0-... GC(13) _eden_chunk_index=2, _eden_chunk_capacity=1281 GC(13) _eden_chunk_array[0]=0x00000000fa700010 GC(13) _eden_chunk_array[1]=0x00000000fa7321b0 GC(13) survivor 0x00000000fb000000-0x00000000fb700070-... GC(13) _survivor_chunk_index=0, _survivor_chunk_capacity=5120 GC(13) Rescan (parallel) GC(13) oops_do_marking_prologue GC(13) WorkerManager::add_workers() : created_workers: 6 GC(13) GC Thread: using 6 out of 6 workers ... GC(13) Pause Remark 62M->62M(80M) 1.288ms GC(13) User=0.00s Sys=0.00s Real=0.00s -- Remark phase, Pause -- 6 threads used as specified by -XX:ParallelGCThreads=6 GC(13) Concurrent Sweep GC(13) size[3] : GC(13) demand: 0, old_rate: 40633.671875, current_rate: 0.000000, ... ... GC(13) Concurrent active time: 0.007ms GC(13) (CMS Concurrent Sweep yielded 1 times) GC(13) Concurrent Sweep 7.251ms -- Sweep phase, Concurrent GC(13) User=0.00s Sys=0.02s Real=0.01s GC(13) Old: 32486K->32486K(61440K) -- GC #13 (Old GC) completed
As you can see, the "-XX:ConcGCThreads=5" option works as expected. The "Mark" and "Remark" phase used 5 threads.
Conclusion: CMS Old GC has 6 phases. But not all phases supports multiple threads:
Phases Threads JVM Option Concurrency Initial Mark 6 ParallelGCThreads pause - stop-the-world Mark 5 ConcGCThreads concurrent to app/ParNew Preclean 1 concurrent to app/ParNew Abortable Preclean 1 concurrent to app/ParNew Remark 6 ParallelGCThreads pause stop-the-world Sweep 1 concurrent to app/ParNew
Table of Contents
Heap Memory Area and Size Control
JVM Garbage Collection Logging
Introduction of Garbage Collectors
Serial Collector - "+XX:+UseSerialGC"
Parallel Collector - "+XX:+UseParallelGC"
►Concurrent Mark-Sweep (CMS) Collector - "+XX:+UseConcMarkSweepGC"
What Is Concurrent Mark-Sweep (CMS) Collector
Concurrent Mark-Sweep Collector GC Log Message Format
Reduce Stop-The-World with Concurrent Mark and Sweep
Parallel New (ParNew) Collector for Minor GC
ParNew Collector - Tenuring Age Distribution
Maximum Logging of All Phases on Young GC
"-XX:ParallelGCThreads=6" - Young GC Parallel Threads
"-XX:MaxTenuringThreshold=0" - Tenuring Objects Immediately
"-XX:CMSInitiatingOccupancyFraction=20" - Initiate CMS
Maximum Logging of All Phases on Old GC
Maximum Logging of All Phases on Full GC
"-XX:ParallelGCThreads=6" - Old GC Parallel Threads
►"-XX:ConcGCThreads=3" - Old GC Concurrent Threads
Garbage First (G1) Collector - "+XX:+UseG1GC"
The Z Garbage Collector (ZGC) - "+XX:+UseZGC"
Object References and Garbage Collection
Garbage Collection Performance Test Program
Performance Tests on Serial Collector
Performance Tests on Parallel collector
Performance Tests on Concurrent collector
Performance Tests on G1 collector