JDK-8244603 : G1 incorrectly limiting young gen size when using the reserve can result in repeated full gcs
  • Type: Bug
  • Component: hotspot
  • Sub-Component: gc
  • Affected Version: 15
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2020-05-07
  • Updated: 2021-07-26
  • 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 :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
In the heuristic to calculate the young gen size there is a part that limits the previously calculated desired size to what is actually available:

  // We will try our best not to "eat" into the reserve.
  uint absolute_max_length = 0;
  if (_free_regions_at_end_of_collection > _reserve_regions) {
    absolute_max_length = _free_regions_at_end_of_collection - _reserve_regions;
  }

I.e. if the amount of free regions is larger than the regions in the reserve, try to allocate until the start of the reserve. (Which is debatable, as the reserve itself is supposed to be used...)

However this misses the situation when the number of free regions is already smaller than the reserve - in this case the amount of free regions the caller gets is *not* bounded by anything anymore, meaning that the heuristic may hand out more regions than are actually available, i.e. the mutator will use up all available regions.

Which means that G1 will run into evacuation failures, and eventually in a full gc ("Attempting maximally compacting GC") as the evacuation failure handling does not guarantee to free any region.

In some cases this can lead to G1 running into such evacuation failure/full gcs over and over again as this leads to an extremely high old gen allocation rate (ie. the regions where evacuation failed).

Note that the resulting evac failure/full gc is fine - the problem is that the heuristic hands out too many regions all the time, which leads to old gen filling up very quickly (with almost empty regions), not giving the marking enough time to complete.

Adaptive IHOP in these cases can't lower the threshold fast enough in these cases.
Comments
Changeset: 0f2ac202 Author: Thomas Schatzl <tschatzl@openjdk.org> Date: 2020-06-25 16:07:43 +0000 URL: https://git.openjdk.java.net/amber/commit/0f2ac202
02-07-2020

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

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