RFR: 8254315: Shenandoah: Concurrent weak reference processing [v3]
Roman Kennke
rkennke at openjdk.java.net
Fri Oct 9 17:33:19 UTC 2020
> Until now, references (as in java.lang.ref.Reference and its subclasses WeakReference, SoftReference, PhantomReference
> and the non-public FinalReference - I'll collectively call them weak references for the purpose of clarity). Workloads
> that make heavvy use of such weak references will therefore potentially cause significant GC pauses. There are 3 main
> items that contribute to pause time linear to number of references, or worse:
> - We need to scan and consider each reference on the various 'discovered' lists.
> - We need to mark through subgraph of objects that are reachable only through FinalReference. Notice that this is
> theoretically only bounded by the live data set size.
> - Finally, all no-longer-reachable references need to be enqueued in the 'pending list'
>
> The problem is somewhat mitigated by pre-cleaning the discovered list: Any weak reference that we find to be strongly
> reachable will be removed before we go into the final-mark-pause. However, that is only a band-aid.
> The solution to this is two-fold:
> 1. Extend concurrent marking to also mark the 'finalizable' subgraph of the heap. This requires to extend the marking
> bitmap to allow for two kinds of reachability: each object can now be strongly and finalizably reachable. Whenever
> marking encounters a FinalReference, it will mark through the referent and switch to 'finalizably' reachability for all
> objects starting from the referent. When marking encounters finalizably reachable objects while marking strongly, it
> will 'upgrade' reachability of such objects to strongly reachable. All of this can be done concurrently. Any encounter
> of a Reference (or subclass) object will enqueue that object into a thread-local 'discovered' list. Except for
> FinalReference, marking stops there, and does not mark through the referent. 2. Concurrent processing is performed
> after the final-mark pause. GC workers scan all discovered lists that have been collected by concurrent marking, and
> depending on reachability of the referent, either drop the Reference, or enqueue it into the global 'pending' list
> (from where it will be processed by Java reference handler thread). In addition to that, we must ensure that no
> referents become resurrected by accessing Reference.get() on it. In order to achieve this, we employ special barriers
> in Reference.get() intrinsics that return NULL when the referent is not reachable.
Roman Kennke has updated the pull request with a new target base due to a merge or a rebase. The pull request now
contains 33 commits:
- Merge remote-tracking branch 'upstream/master' into shenandoah-concurrent-weakrefs
- Use existing idiom for checking for intanceRefKlass, instead of introducing new code
- Add precompiled header to shenandoahMarkBitMap.cpp
- Fix null-check after C2 native-LRB
- Reinstate check for ShenandoahSelfFixing that got lost during the merge
- Merge branch 'master' into shenandoah-concurrent-weakrefs
- Add Oracle copyright header to shenandoahReferenceProcessor.[hc]pp due to its structural origins from its ZGC
couterparts
- Relax assert in reference processor to account no LRB in passive mode
- Aarch64 support for concurrent weak references/extended native barriers
- Perform reference-processing during full-GC and degenerated-GC
- ... and 23 more: https://git.openjdk.java.net/jdk/compare/52e45a36...aaf8717f
-------------
Changes: https://git.openjdk.java.net/jdk/pull/505/files
Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=505&range=02
Stats: 2285 lines in 50 files changed: 1539 ins; 565 del; 181 mod
Patch: https://git.openjdk.java.net/jdk/pull/505.diff
Fetch: git fetch https://git.openjdk.java.net/jdk pull/505/head:pull/505
PR: https://git.openjdk.java.net/jdk/pull/505
More information about the shenandoah-dev
mailing list