Blocks :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
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.
|