RFR: 8321816: GenShen: Provide a minimum amount of time for an old collection to run [v4]
William Kemper
wkemper at openjdk.org
Thu Dec 21 03:26:09 UTC 2023
On Thu, 21 Dec 2023 03:08:39 GMT, William Kemper <wkemper at openjdk.org> wrote:
>> src/hotspot/share/gc/shenandoah/shenandoahRegulatorThread.cpp line 67:
>>
>>> 65: }
>>> 66:
>>> 67: void ShenandoahRegulatorThread::regulate_young_and_old_cycles() {
>>
>> I am wondering if it might not be simpler and clearer to write this method as:
>>
>>
>> ...
>> while (!should_terminate()) {
>> switch (mode) {
>> case SCT::none : {
>> // no collection is in progress
>> // 1. check and start a global collection if needed
>> if (should_unload_classes() && start_global_cycle()) {
>> log_info...
>> } else if (start_old_cycle()) {
>> // 2. else check and start an old cycle
>> log_info...
>> } else if (start_young_cycle()) {
>> // 3. else check and start a young cycle
>> log_info...
>> }
>> break;
>> }
>> case SCT::servicing_old: {
>> // if an old collection is in progress, check if a young
>> // collection is needed. We can't start a global collection
>> // in this state, even if one is needed.
>> if (start_young_cycle()) {
>> log_info...
>> }
>> break;
>> }
>> default: // fall through
>> }
>> // sleep a tad before next check; sleep duration inversely proportional to allocation rate
>> regulator_sleep(); // My worry is that heuristics says wait for old increment and we sleep longer than that? May be that's not an issue?
>> }
>> ...
>>
>>
>> The rest of the checks etc. seem already to be done in the `start_...` methods from what I can tell.
>>
>> I may have missed some subtlety though.
>
> When regulating young and old cycles (i.e., generational mode), the regulator overrides the global heuristics decision to start a global cycle. In other modes, whether or not to unload classes is decided _after_ a cycle is started. However, the generational mode can only unload classes in a _global_ cycle, so we use the oom in metaspace to _trigger_ a global cycle (even if the global heuristic would not otherwise trigger a cycle).
>
> The other subtlety here is that old cycles are only started when a young cycle wants to run. Each old cycle is preceded by a young "bootstrap" cycle, so the young heuristic trigger is still satisfied. This was meant to avoid the situation where old cycles are triggered shortly after a young cycle - which runs an unproductive "bootstrap" cycle. This is why we check the young heuristic and then the old heuristic before starting an old cycle.
>
> Your comment about starting a global cycle (to unload classes) even during an old cycle is interesting though. There's no specific reason why we couldn't interrupt and abandon the old cycle in this case, but I think that's a change for another PR.
I'm not too worried about the regulator's sleep method. The new flag introduces a delay if an old cycle is running, but the delay to start a young cycle because the regulator thread was sleeping is unchanged. Note that the feature can also be disabled by setting `ShenandoahMinimumOldMarkTimeMs` to zero.
-------------
PR Review Comment: https://git.openjdk.org/shenandoah/pull/371#discussion_r1433415130
More information about the shenandoah-dev
mailing list