RFR: Traveral GC heuristics
Zhengyu Gu
zgu at redhat.com
Wed Jan 17 20:56:45 UTC 2018
On 01/17/2018 03:54 PM, Roman Kennke wrote:
> Am 17.01.2018 um 18:10 schrieb Zhengyu Gu:
>> shenandoahOopClosures.hpp:
>> Missing string dedup version
>
> I am not sure what needs to be done for strdedup. Add support for it in
> a followup patch?
Sure. I can add the support afterward.
Thanks,
-Zhengyu
>
>> shenandoahSupport.cpp
>> L#615 - 656
>> L#3537 - 3556
>> L#3981 - 4056
>> indent
>
> Fixed.
>
>> sharedRuntime.cpp
>>
>> 213 assert(oopDesc::is_oop(orig, true /* ignore mark word */),
>> "Error");
>> 214 // store the original value that was in the field reference
>> 215 if (UseShenandoahGC) { ShenandoahBarrierSet::enqueue(orig); }
>> 216 return;
>> 217 thread->satb_mark_queue().enqueue(orig);
>> 218 JRT_END
>>
>> L#216: does not look right. Should it be inside UseShenandoahGC block?
>
> It's not needed and can go away.
>
> You'll find the updated patch in reply to Aleksey's review that I'll
> post shortly (after testing).
>
> Thanks, Roman
>
>> Thanks,
>>
>> -Zhengyu
>>
>>
>> On 01/17/2018 09:37 AM, Roman Kennke wrote:
>>> Testing showed up some regressions in non-traversal code and two
>>> issues that I introduced (or haven't fixed) when single-flag patch
>>> arrived.
>>>
>>> The following now passes hotspot_gc_shenandoah tests and runs of
>>> specjvm with fastdebug with -XX:+ShenandoahVerify
>>> -XX:+ShenandoahGCHeuristics=traversal, with -XX:TieredStopAtLevel=0|1|4
>>>
>>> Differential:
>>> http://cr.openjdk.java.net/~rkennke/traversal/webrev.01.diff/
>>> Full:
>>> http://cr.openjdk.java.net/~rkennke/traversal/webrev.01/
>>>
>>> Please review, test, comment, etc. :-)
>>>
>>> Cheers, Roman
>>>
>>>> This started out as a smallish partial-GC experiment, then into a
>>>> clone of partial GC, and ended up as a standalone GC mode for
>>>> Shenandoah, which is a frankensteinization of
>>>> partial+concurrent-marking, with some goodies :-)
>>>>
>>>> The idea is to do everything, marking+evacuation+update-refs, in one
>>>> single phase. This is not very difficult to do: while traversing,
>>>> evacuate objects that are in the Cset, and update references as we
>>>> go. I chose to traverse the heap using an incremental-update
>>>> approach, mostly because this is what partial GC does, and as said
>>>> above, this started out as a clone of partial :-)
>>>>
>>>> The tricky part is to choose the Cset: I made it such that each GC
>>>> cycle collects liveness information, and bases the decision about
>>>> Cset in the next cycle on that liveness information. Yes, this means
>>>> the first cycle does not collect anything (except immediate garbage).
>>>>
>>>> Advantages:
>>>> - obviously, touching all live objects only once means less time
>>>> spent in GC. Measurements show that traversing the heap and doing
>>>> everything is only slightly longer than Shenandoah's marking phase,
>>>> and this might actually be because we also need to mark through
>>>> newly allocated objects.
>>>> - Traversal-order evacuation gives us 10x increase in
>>>> ordering-sensitive microbenchmark:
>>>> https://shipilev.net/jvm-anatomy-park/11-moving-gc-locality/
>>>>
>>>> - Simpler barriers: i-u style barriers don't need to load the
>>>> pre-value, and can be optimized much better (hoisted out of hot
>>>> paths, etc). Some of it is already done in this patch, but there are
>>>> plenty of opportunities to make it even better.
>>>> - Possibly less floating garbage because we trace through newly
>>>> allocated objects too, and don't treat it implicitely live.
>>>> - we don't need a keep-alive-barrier for Reference.get() which means
>>>> we keep fewer referents alive just because they happen to be
>>>> accessed during GC.
>>>> - MWF is only a switch away (if I understand MWF correctly):
>>>> -XX:+ShenandoahMWF
>>>> - It does not need RBs in the WB fast-path, because outside of the
>>>> single phase, nothing is ever forwarded.
>>>> - It does not need the membar stuff in the WBs because we turn
>>>> on/off the phase during safepoint
>>>>
>>>> Disadvantages:
>>>> - Store-value barrier needs to be a WB, RB is not sufficient. The
>>>> storeval barrier is there to ensure only to-space values ever get
>>>> written to fields during update-refs. 3-phase Shenandoah doesn't
>>>> evacuate during update-refs, and therefore RB is enough. We need WB
>>>> here. (I believe this is off-set by optimization opportunities, see
>>>> above)
>>>> - Known I-U problem: mutators can outrun the GC with allocations and
>>>> let us not terminate.
>>>> - It needs barriers for constants (need to check this).
>>>>
>>>> Stuff left to do:
>>>> - Implement sane degeneration: if we hit OOM, we simply restart and
>>>> go into full-GC.
>>>> - Depending on degen: make heuristics adaptive. Currently it
>>>> requires manual tweaking of thresholds.
>>>>
>>>> Relevant knobs:
>>>> - ShenandoahGarbageThreshold: regions with more garbage than this go
>>>> into the Cset. Notice that this is based on the *previous* cycle, so
>>>> we may actually have much more garbage (but not less).
>>>> - ShenandoahFreeThreshold: start GC when we have less than that much
>>>> free heap.
>>>>
>>>> I'll not go into all the details for now and give you the code:
>>>> http://cr.openjdk.java.net/~rkennke/traversal/webrev.00/
>>>>
>>>>
>>>> Roman
>>>
>
More information about the shenandoah-dev
mailing list