Collection set is empty -> conc mark cancelled

Aleksey Shipilev shade at redhat.com
Thu Nov 24 13:40:44 UTC 2016



On 11/24/2016 02:31 PM, Aleksey Shipilev wrote:
> Hi,
> 
> On 11/24/2016 02:17 PM, Roman Kennke wrote:
>> Interestingly, I ran into this myself when I played with heuristics
>> yesterday :-)
>>
>>> My question is: what's the purpose for that _collection_set->count()
>>> ==
>>> 0 check?
>>
>> dunno. The idea might have been that if the cset ends up empty,
>> something is wrong. But as you say, it seems superfluous.
>>
>>>  Seems superfluous to me, because we had already had our mark,
>>> and heading to conc evac. What are we canceling? Seems incorrect to
>>> assume that empty collection set is somehow the detractor from
>>> the  conc
>>> mark -- like in the benchmark above, where rootset mutates, but no
>>> garbage is effectively produced.
>>>
>>> Or, at very least, should we reset the concgc flag somewhere else?
> 
> It is being reset after full GC. All other uses of cancel_concgc()
> trigger the full GC, except this one. So, there are two options:
> 
>  a) Drop the cset-is-empty check, and probably spin back to concurrent
> mark again on the next cycle;
> 
> -    if (_collection_set->count() == 0)
> -      cancel_concgc();
> -
> 
> 
>  b) Cancel the mark, but also schedule the full GC:
> 
> -    if (_collection_set->count() == 0)
> +    if (_collection_set->count() == 0) {
> +      concurrent_thread()->schedule_full_gc();
>        cancel_concgc();
> +    }
> 
> 
> Both options resolve the hiccup. The question is, do we need to treat
> empty cset specially or not? Since this is a corner case, we may want to
> play it safe with option (b). Thoughts?

OTOH, it is bad to punish the garbage-free application with full GCs
here. Even heuristics would not save us here: "aggressive" would trigger
mark, discover no garbage, and do the full GC nevertheless.

Thanks,
-Aleksey



More information about the shenandoah-dev mailing list