RFR: Fold Partial GC into Traversal GC
Roman Kennke
rkennke at redhat.com
Thu Apr 12 08:58:36 UTC 2018
Back then, the Traversal GC mode started out as special configuration of
partial GC (i.e. put all used regions into cset and none into root set).
Then I forked partial GC to put in some extras without disturbing
existing code, and because it needed slight changes to the algorithm
that didn't really fit with partial GC.
Now I'm proposing to fold the partial mode into Traversal GC, and make
Traversal GC the intermediate GC for partial. This has some great
advantages:
- Partial and traversal can then use the same barriers. No need for
ConditionalSATBBarrier just to support the occasional conc-mark.
- Weakref and Class unloading during partial GC, yay!
- Partial GC would benefit from all the optimized loops and barriers in
traversal GC.
Both GC modes are traversing through the heap. The difference is that
partial GC only traverses through a subset (the cset), and stops
traversal on pointers outside of the cset. And of course, it needs to
scan the root regions.
Algorithm-wise there are not that many differences:
- partial uses object location to determine if object has already been
visited: if it's in cset, then it's not visited, if it's already
evacuated, then it has been visited and can be ignored. Traversal also
needs to traverse through stuff outside the cset and uses mark bitmaps.
- partial scans root regions before traversing to collect pointers from
outside cset into cset.
In order to be able to get Traversal GC to also handle partial GC, only
few things need to be done:
- Scan root-regions if there are any
- Introduce a new 'view' of our heap regions that I'm calling the
traversal set to identify oops that need to be traversed (or not).
Traversal-Set is a superset of collection-set. Stuff in the traversal
set gets traversed-through (and updated, etc), but not evacuated. For
example, to get the current traversal mode, we put all used regions into
traversal set, the usual regions into cset and no regions into root set.
In order to get the current partial GCs, we put cset==traversal-set and
the usual root-regions.
- Handle partial marking information (see below)
It turns out that generating marking information during partial GC is
useful: it means we can use it for bitmap-based-scanning. This was not
possible before because partial-gc would not create/update marking info,
only the intermediate conc-mark would do that.
The way we handle it is as follows:
- At start of cycle, we reset all TAMS for non-traversal-regions to
bottom. This means we treat everything outside the traversal-set as
live, and thus don't create marking info. Notice that root-scanning uses
the *complete* (i.e. pre-existing) bitmap and thus does *not* treat
everything live.
- After cycle, we have marking info for everything in t-set. We copy
those parts to the complete bitmap, from then on it can be used for
bitmap-based-scanning (in subsequent cycles).
- The next bitmap for t-set gets cleaned after cycle so that next cycle
can start with fresh bitmap.
- On region recycling, we reset the complete bitmap parts for the region
too.
IOW, instead of swapping bitmaps (which is not possible anymore because
of partial) we copy the new stuff in next bitmap to the complete bitmap.
There's one part which I did not really know what to do: for the
traversal-set I needed a fast-lookup similar to cset, which I can use to
quickly say for an address if it's in the t-set or not. I basically
copied the ShenandoahCollectionSet code, and ripped out the
cset-specific parts and called it ShenandoahFastRegionSet for now. I am
also using it for root regions now. Based on some earlier discussions
with Aleksey on IRC I wanted to fold it into ShenandoahHeapRegionSet,
but this felt awkward because ShHRS is not really a set, but a list, and
it's sortable (and used for sorting), etc. So I left it as
ShFastRegionSet for now to give some basis for discussions.
I tested this by successfully running hotspot_gc_shenandoah many times
both in release and fastdebug. I ran specjvm multiple times through,
without regressions. It even looks like a smallish improvement for
partial and traversal heuristics.
http://cr.openjdk.java.net/~rkennke/partial-traversal/webrev.00/
Roman
More information about the shenandoah-dev
mailing list