Summary
Processing of j.l.ref.References in the G1 garbage collection pauses should be parallel by default and dynamically adapt the number of threads based on available work.
Problem
Users currently need to manually turn on parallel processing for java.lang.ref.References during a G1 gc pause. This is an all-or-nothing setting: when turned on, G1 uses all available threads (as set by -XX:ParallelGCThreads) for this phase, that itself consists of several subphases, independent of available work. This means that often when in a particular garbage collection, or in a particular subphase of java.lang.ref.Reference processing there is not a lot of work to do, G1 still needs to start up and synchronize all threads for shutdown. Starting up and synchronizing threads for shutdown immediately afterwards can take a relatively long amount of time due to interaction with the operating system. So a user can select between potentially a slow java.lang.ref.Reference processing phase if there is lots of work to do, or performance losses due to java.lang.ref.Reference processing when there is not a lot of work to do.
Solution
For G1 we will by default enable parallel java.lang.ref.Reference processing and use the existing mechanism where G1 tries to select a more optimal number of threads based on heuristics the amount of work per sub-phase of java.lang.ref.Reference processing.
Specification
For the G1 collector, the default value for the ParallelRefProcEnabled option will be true if more than one thread is used and not otherwise overridden. I.e.
--- old/src/hotspot/share/gc/g1/g1Arguments.cpp 2018-06-08 15:53:28.148957195 +0200
+++ new/src/hotspot/share/gc/g1/g1Arguments.cpp 2018-06-08 15:53:27.788945904 +0200
@@ -122,6 +122,10 @@
FLAG_SET_DEFAULT(GCPauseIntervalMillis, MaxGCPauseMillis + 1);
}
+ if (FLAG_IS_DEFAULT(ParallelRefProcEnabled) && ParallelGCThreads > 1) {
+ FLAG_SET_DEFAULT(ParallelRefProcEnabled, true);
+ }
+
log_trace(gc)("MarkStackSize: %uk MarkStackSizeMax: %uk", (unsigned int) (MarkStackSize / K), (uint) (MarkStackSizeMax / K));
The mechanism to select the number of parallel threads uses the existing flag ReferencesPerThread that determines the number of threads to be used for this phase: for every ReferencesPerThread java.lang.ref.References to work on, add another thread up to the current maximum as determined elsewhere.
To reiterate, only G1 observes ReferencesPerThread at this time. So using -XX:+ParallelRefProcEnabled with other collectors behaves the same as before, i.e. all currently available threads are used for parallel reference processing.
- csr of
-
JDK-8205043 Make parallel reference processing default for G1
-
- Resolved
-