Java GC Tutorials - Herong's Tutorial Examples - v1.12, by Herong Yang
"-XX:ParallelGCThreads=6" - Old GC Parallel Threads
This section demonstrates that the '-XX:ParallelGCThreads=6' option can be used to control the number of threads used in Old GC parallel phases.
In previous tutorials, we learned that multiple threads are used by the CMS collector for stop-the-world (application paused) phases in an Old GC process.
For example, we saw 2 threads was used in the "Initial Mark" phase. If you want to increase the number of threads used in those stop-the-world phases, you can specify a higher number in the "-XX:ParallelGCThreads=n" option.
The example below shows all log messages of a single Old GC performed by the CMS collector with 6 threads specified in stop-the-world phases.
herong> java -XX:+UseConcMarkSweepGC \ -Xms90m -Xmx90m -XX:NewRatio=2 -XX:SurvivorRatio=1 \ -XX:CMSInitiatingOccupancyFraction=20 \ -XX:+UseCMSInitiatingOccupancyOnly \ -XX:ParallelGCThreads=6 \ -Xlog:gc*=trace \ GarbageCollection2 > output.txt herong> more output.txt GC(4) Pause Initial Mark GC(4) checkpointRootsInitialWork GC(4) eden 0x00000000fa600000-0x00000000fa700010-0x0000... GC(4) _eden_chunk_index=1, _eden_chunk_capacity=1281 GC(4) _eden_chunk_array[0]=0x00000000fa700010 GC(4) survivor 0x00000000fb000000-0x00000000fb900090-0x0000... GC(4) _survivor_chunk_index=0, _survivor_chunk_capacity=5120 GC(4) oops_do_marking_prologue GC(4) WorkerManager::add_workers() : created_workers: 6 GC(4) GC Thread: using 6 out of 6 workers GC(4) Finished young gen initial mark scan work in 2th thread: 0.000 sec GC(4) Finished young gen initial mark scan work in 5th thread: 0.000 sec GC(4) Finished young gen initial mark scan work in 1th thread: 0.000 sec GC(4) Finished young gen initial mark scan work in 0th thread: 0.000 sec GC(4) Finished young gen initial mark scan work in 3th thread: 0.000 sec GC(4) Finished remaining root initial mark scan work in 2th thread: 0.000 sec GC(4) Finished remaining root initial mark scan work in 0th thread: 0.000 sec GC(4) Finished remaining root initial mark scan work in 1th thread: 0.000 sec GC(4) Finished young gen initial mark scan work in 4th thread: 0.000 sec GC(4) Finished remaining root initial mark scan work in 3th thread: 0.000 sec GC(4) Finished remaining root initial mark scan work in 5th thread: 0.000 sec GC(4) Finished remaining root initial mark scan work in 4th thread: 0.000 sec GC(4) WorkerManager::add_workers() : created_workers: 6 GC(4) GC Thread: using 6 out of 6 workers GC(4) oops_do_marking_epilogue GC(4) checkpointRootsInitialWork 0.268ms GC(4) Pause Initial Mark 27M->27M(80M) 0.302ms GC(4) User=0.00s Sys=0.00s Real=0.00s -- Initial Mark phase, Pause -- 6 threads used as specified by -XX:ParallelGCThreads=6 GC(4) Concurrent Mark GC(4) CMS Thread: using 2 out of 2 workers GC(4) Using 2 workers of 2 for marking GC(4) Finished cms space scanning in 0th thread: 0.007 sec GC(4) Finished cms space scanning in 1th thread: 0.007 sec GC(4) Finished work stealing in 1th thread: 0.000 sec GC(4) Finished work stealing in 0th thread: 0.000 sec GC(4) Concurrent active time: 0.002ms GC(4) (CMS Concurrent Mark yielded 1 times) GC(4) Concurrent Mark 7.556ms GC(4) User=0.03s Sys=0.00s Real=0.02s -- Mark phase, Concurrent -- 2 threads used by default GC(4) Concurrent Preclean GC(4) Preclean SoftReferences 0.028ms GC(4) Preclean WeakReferences 0.039ms GC(4) Preclean FinalReferences 0.020ms GC(4) Preclean PhantomReferences 0.024ms GC(4) Concurrent Preclean 0.418ms GC(4) User=0.00s Sys=0.00s Real=0.00s -- Preclean phase, Concurrent GC(4) Concurrent Abortable Preclean GC(4) Concurrent Abortable Preclean 36.072ms GC(4) User=0.11s Sys=0.02s Real=0.03s -- Abortable Preclean phase, Concurrent
GC(4) Pause Remark GC(4) YG occupancy: 7371 K (20480 K) GC(4) checkpointRootsFinalWork GC(4) eden 0x00000000fa600000-0x00000000fa731f70-0x0000... GC(4) _eden_chunk_index=2, _eden_chunk_capacity=1281 GC(4) _eden_chunk_array[0]=0x00000000fa700010 GC(4) _eden_chunk_array[1]=0x00000000fa731f70 GC(4) survivor 0x00000000fba00000-0x00000000fc001080-0x0000... GC(4) _survivor_chunk_index=0, _survivor_chunk_capacity=5120 GC(4) Rescan (parallel) GC(4) oops_do_marking_prologue GC(4) WorkerManager::add_workers() : created_workers: 6 GC(4) GC Thread: using 6 out of 6 workers GC(4) Finished young gen rescan work in 0th thread: 0.000 sec GC(4) Finished young gen rescan work in 3th thread: 0.000 sec GC(4) Finished young gen rescan work in 1th thread: 0.000 sec GC(4) Finished young gen rescan work in 2th thread: 0.000 sec GC(4) Finished young gen rescan work in 5th thread: 0.000 sec GC(4) Finished remaining root rescan work in 1th thread: 0.000 sec GC(4) Finished remaining root rescan work in 2th thread: 0.000 sec GC(4) Finished remaining root rescan work in 0th thread: 0.000 sec GC(4) Finished young gen rescan work in 4th thread: 0.000 sec GC(4) Finished unhandled CLD scanning work in 0th thread: 0.000 sec GC(4) Finished remaining root rescan work in 3th thread: 0.000 sec GC(4) Finished remaining root rescan work in 4th thread: 0.000 sec GC(4) Finished dirty CLD scanning work in 0th thread: 0.000 sec GC(4) Finished remaining root rescan work in 5th thread: 0.000 sec GC(4) Finished dirty card rescan work in 0th thread: 0.000 sec GC(4) Finished dirty card rescan work in 2th thread: 0.000 sec GC(4) Finished dirty card rescan work in 1th thread: 0.000 sec GC(4) Finished dirty card rescan work in 4th thread: 0.000 sec GC(4) Finished dirty card rescan work in 5th thread: 0.000 sec GC(4) Finished dirty card rescan work in 3th thread: 0.000 sec GC(4) Finished work stealing in 0th thread: 0.000 sec GC(4) Finished work stealing in 2th thread: 0.000 sec GC(4) Finished work stealing in 3th thread: 0.000 sec GC(4) Finished work stealing in 1th thread: 0.000 sec GC(4) Finished work stealing in 4th thread: 0.000 sec GC(4) Finished work stealing in 5th thread: 0.000 sec GC(4) WorkerManager::add_workers() : created_workers: 6 GC(4) GC Thread: using 6 out of 6 workers ... GC(4) Pause Remark 63M->63M(80M) 1.261ms GC(4) User=0.00s Sys=0.00s Real=0.00s -- Remark phase, Pause -- 6 threads used as specified by -XX:ParallelGCThreads=6 GC(4) Concurrent Sweep GC(4) Concurrent Sweep 7.167ms -- Sweep phase, Concurrent GC(4) User=0.02s Sys=0.00s Real=0.02s GC(4) Old: 18246K->31462K(61440K) -- GC #4 (Old GC) completed
As you can see, the "-XX:ParallelGCThreads=6" option works as expected. Both "Initial Mark" and "Remark" phases used 6 threads.
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