JDK-8243672 : Short term pause time ratio calculation in G1 off
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: gc
  • Affected Version: 15
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2020-04-27
  • Updated: 2020-07-02
  • Resolved: 2020-06-25
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 16
16 b04Fixed
Related Reports
Blocks :  
Blocks :  
Description
G1 calculates short term pause time ratio by

ratio = (current pause time * X) (time of current end of gc - current-Xth end of gc)

where X is the current length of the queue containing the last X end-of-gc pause times. (This is to smooth out spikes in collections that are close together).

The problem is that G1 pushes the current collection end time *before* this calculation onto that queue, which means that the denominator in above calculation uses one less period than required. 
Comments
Changeset: 8c204010 Author: Thomas Schatzl <tschatzl@openjdk.org> Date: 2020-06-25 16:07:39 +0000 URL: https://git.openjdk.java.net/amber/commit/8c204010
02-07-2020

Changeset: 8c204010 Author: Thomas Schatzl <tschatzl@openjdk.org> Date: 2020-06-25 16:07:39 +0000 URL: https://git.openjdk.java.net/mobile/commit/8c204010
02-07-2020

URL: https://hg.openjdk.java.net/jdk/jdk/rev/a79d8b29160e User: tschatzl Date: 2020-06-25 14:08:46 +0000
25-06-2020

Actually this way of calculating the pause time ratio (assuming that the current's pause time across multiple mutator-gc cycles) can actually unintentially emphasize recent gc pauses, contrary to the comment: // Compute the ratio of just this last pause time to the entire time range stored // in the vectors. Comparing this pause to the entire range, rather than only the // most recent interval, has the effect of smoothing over a possible transient 'burst' // of more frequent pauses that don't really reflect a change in heap occupancy. // This reduces the likelihood of a needless heap expansion being triggered. I.e. consider the frequency of the GCs fairly equal, and the most recent GC taking much longer than any of the others. E.g. 500ms mutator time between N=10 GCs, the previous nine times there has been a 20ms GC pause (young only gc), then a 200ms mixed gc, results in a gc time ratio of (200 * 10) / ((500 + 20) * 9 + 500 + 200) = 2000 / 5380 = 0,37, i.e. 37% pause time ratio (current) vs. if you calculated correctly (200 + 9 * 20) / ((500 + 20) * 9 + 500 + 200) = 380 / 5380 = 0,071, i.e. 7% pause time ratio (actual) at that point. 37% is significantly different than the 7% expected. This (in a somewhat less accentuated way) actually occurs in applications where you manually set an MMU (not the default 200/201) on a constant load (e.g. specjbb2015 fixed ir 20k, but any is basically fine). The result is that ultimately G1 will expand to full heap due to these regular pause time ratio spikes (if it does more than 4 mixed gcs as the threshold for expanding the heap is 4 such pause time ratios above the threshold) if e.g. the mixed gcs are much longer than young-only gcs.
29-04-2020