FYI: Some notes on java.lang.ref.Reference processing in JDK11
Thomas Schatzl
thomas.schatzl at oracle.com
Mon Jun 18 11:00:41 UTC 2018
Hi all,
in JDK11 there are significant changes in how the garbage collectors
process instance of java.lang.ref.References (subclasses of
SoftReferences, WeakReferences, PhantomReferences).
Since over time there have been a few reports of in particular G1
reference processing being too slow, I thought I would write a heads up
post on latest changes in this area:
- the 9-phase reference processing has been cut down to a 4-phase
reference processing in all collectors.
This saves a lot of time, particularly when doing parallel reference
processing. I.e. worker threads do not need to be started up and waited
for during shutdown as often.
Due to that, the log output had to change, see http://mail.openjdk.java
.net/pipermail/hotspot-gc-dev/2018-June/022264.html for details, and ht
tps://bugs.openjdk.java.net/browse/JDK-8202845 for the CR.
- the "Reference Enqueue" phase has been merged into the actual
reference processing phases. This GC phase does not exist any more. See
https://bugs.openjdk.java.net/browse/JDK-8202017 for more information.
- G1 received most changes:
- reference processing throughput should now be on par with other
collectors (e.g. CMS) or at least much better.
- G1 drops the now unnecessary "Preserve CM Referents" GC phase due
to internal changes. This phase does not exist any more. See https://bu
gs.openjdk.java.net/browse/JDK-8201492 for a few more details.
- G1 implements a concurrent precleaning phase like CMS, which is
enabled by default. It can be disabled using -XX:-
G1UseReferencePrecleaning if this lengthens the concurrent phase
too much for you.
CR is at https://bugs.openjdk.java.net/browse/JDK-8201491 .
- if parallel reference processing is enabled, G1 tries to optimally
size the number of worker threads for a given phase. This number of
threads is determined by dividing the number of
java.lang.ref.References by the value of -XX:ReferencesPerThread
(default: 1000).
This makes the startup and shutdown of parallel threads overhead
smaller for cases when there is not much work to do, speeding up the
process significantly.
If you set ReferencesPerThread to zero (0), you will get the old
behavior.
Other collectors than G1 will still use all currently active threads
for reference processing.
Also, if there is no work to do for a particular phase (e.g. you were
diligent in not having any Finalizers :) ), these phases are skipped
completely (no startup/shutdown of gc worker threads at all; this part
of the change applies to all collectors).
CR is at https://bugs.openjdk.java.net/browse/JDK-8204612 .
All of the above changes will very likely be in the next 11-ea build if
they were not yet.
Further there are plans to make parallel reference processing in
conjunction with dynamic thread sizing default in G1 as in our tests
this gives signficant improvements overall.
Review thread at http://mail.openjdk.java.net/pipermail/hotspot-gc-dev/
2018-June/022381.html, see https://bugs.openjdk.java.net/browse/JDK-820
5043 for the CR.
If you previously manually set -XX:ParallelRefProcEnabled in some way,
there will be no change in behavior, so consider looking at your
scripts again.
Thanks,
Thomas
More information about the hotspot-gc-use
mailing list