RFR: 8359348: G1: Improve cpu usage measurements for heap sizing [v3]
Man Cao
manc at openjdk.org
Wed Aug 6 21:15:15 UTC 2025
On Thu, 31 Jul 2025 09:06:40 GMT, Thomas Schatzl <tschatzl at openjdk.org> wrote:
>> Another idea is, instead of using application cpu usage in the divisor (i.e. from the OS), calculate some `mutator-cpu-usage` similar to `gc-pause-cpu-usage` by multiplying time spent in mutator with the active processors.
>>
>> I.e. the resulting formula being:
>>
>> gc-time-ratio_new = (concurrent-cpu-usage + gc-pause-cpu-usage) / (mutator-cpu-usage + gc-pause-cpu-usage)
>> ```
>> where
>>
>> mutator-cpu-usage = #active processors * mutator-duration
>>
>> effectively making it:
>>
>> gc-time-ratio = (concurrent-cpu-usage + gc-pause-cpu-usage) / (#active processors * time-since-last-pause)
>>
>> (`gc-pause-cpu-usage` calculated as before).
>>
>> Which is very similar to the current approach to divide `concurrent-cpu-usage` by some arbitrary threading factor, without needing to know that factor, and incurring inaccuracies because of that.
>>
>> Compare this formula to the current formula for determing `GCTimeRatio`:
>>
>> gc-time-ratio_old = gc-pause-time / time-since-last-pause
>> // multiply with #active-processors on both divisor and dividend, i.e. multiplying by 1
>> = (#active processors * gc-pause-time) / (#active-processors * time-since-last-pause)
>>
>>
>> So just adding the known concurrent cpu usage to the dividend seems... straightforward, and no more susceptible to issues than before with idle mutators.
>>
>> There is dependency on the number of active processors being "constant", but even the old formula uses it implicitly (i.e. the duration of the mutator and the pause is somewhat dependent on the number of active processors anyway due to allocation rate depending on it).
>>
>> What do you all think? This approximation seems to be no worse than the current and the formula suggested in this change to me. Somebody modifying the number of active processors at runtime for the VM, or something like burstable VMs are already very problematic.
>
>> Which is very similar to the current approach to divide concurrent-cpu-usage by some arbitrary threading factor, without needing to know that factor, and incurring inaccuracies because of that.
>
> Effectively it divides that concurrent-cpu-usage by the number of active processors if I am not mistaken :)
The `#active-processors * time-since-last-pause` approach sounds worth experimenting.
One potential concern is the heap sizing behavior could be more heavily affected by #active-processors, which could be surprising comparing to G1's current behavior. Admittedly, G1's current heap sizing behavior could already be affected by #active-processors (mainly via default values for ParallelGCThreads/ConcGCThreads), but it is likely to a much lesser extent.
If a prototype of this approach exists, we should probably test how much difference in heap sizing there is for an application running with a low value of `ActiveProcessorCount` vs a high value. My main worry is that `#active-processors * time-since-last-pause` could inflate the divisor too much if `#active-processors` is very high (e.g. >100), which could make the heap much smaller, which is quite counter-intuitive.
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/26351#discussion_r2258313156
More information about the hotspot-gc-dev
mailing list