RFR: Single marking bitmap and bitmap cleaning refactoring
Aleksey Shipilev
shade at redhat.com
Thu Sep 13 09:46:58 UTC 2018
http://cr.openjdk.java.net/~shade/shenandoah/single-mark-bitmap/webrev.01/
This includes two logically separate changes that are still better to come together.
1. Single marking bitmap
We have wondered multiple times recently if we actually need two bitmaps: "next"
bitmap and "complete" bitmap. It looks like we do not, and we can save about
1.5% of heap space hoarded by the second bitmap.
There are two major reasons why would you'd like to have two bitmaps.
First, the separation of incomplete (next) and complete bitmaps to isolate bugs,
where we mistakenly assume the bitmap is complete mid-marking. This might as
well be achieved by tracking the "completeness" flag, and rewriting the
accessors to bitmap with complete_marking_ctx (asserting), and marking_ctx
(non-asserting).
Second, the bitmap resets: we maintain "complete" bitmap, while cleaning up
"next" bitmap after the cycle. This helps to have the clean bitmap before
starting the cycle, and having complete marking available for us otherwise. We
can avoid the whole thing by carrying complete bitmap at all times after the
cycle, and only resetting in before the cycle starts. (This might also improve
temporal locality of bitmap accesses, but I am not holding my breath).
It looks that rewiring the bitmaps this way makes traversal cleanups much more
generic. In fact, we don't have to have traversal-special bitmap resets anymore.
It also simplifies asserts, error reporting, and internal profiling code.
2. Refactor bitmap cleanup
Current TAMS machinery is heavily interconnected with bitmap cleanups. For
example, on many paths we resist dropping the TAMS before bitmap cleanups,
because bitmap cleanup would "optimize" and only clear bitmaps up to TAMS. This
can be simplified if we directly track the top-bitmap pointer, which describes
what bitmap parts might be dirty, and use that on cleanup path.
This way, we can drop all the mess about cleaning up bitmaps on region recycling
for Traversal. The change additionally verifies that bitmaps are indeed cleared
properly.
Motivational GC log on Serial:
# Before
GC(7) Pause Init Traversal 1.065ms
GC(7) Concurrent traversal 87104M->87611M(102400M) 1.052ms
GC(7) Pause Final Traversal 0.387ms
GC(7) Concurrent cleanup 87611M->2267M(102400M) 16.964ms // <--- !
# After
GC(7) Concurrent reset 87095M->87095M(102400M) 0.812ms
GC(7) Pause Init Traversal 1.090ms
GC(7) Concurrent traversal 87147M->87555M(102400M) 0.956ms
GC(7) Pause Final Traversal 0.363ms
GC(7) Concurrent cleanup 87555M->2055M(102400M) 0.344ms
Testing: tier3_gc_shenandoah {fastdebug|release}, eyeballing gc logs
Thanks,
-Aleksey
More information about the shenandoah-dev
mailing list