RFR: 8245511: G1 adaptive IHOP does not account for reclamation of humongous objects by young GC
Thomas Schatzl
thomas.schatzl at oracle.com
Mon Aug 10 09:59:50 UTC 2020
Hi,
apologies for the delay. Other things (jdk15 release, vacations) kept
me from getting to this change in time:
On 17.07.20 22:58, Luo, Ziyi wrote:
> Hi,
>
> Please review this patch to adjust the old gen allocation rate for G1 Adaptive
> IHOP to consider the humongous objects freed by young collector.
>
> Webrev: http://cr.openjdk.java.net/~bmathiske/8245511/webrev.01/
> CR: https://bugs.openjdk.java.net/browse/JDK-8245511
>
> This revision addresses a comment from Thomas in webrev.00:
>> one other improvement could be to put the old gen allocation tracking into
> its own class...
>
> This is added in JDK-8245511. This RFR refactors G1*IHOPControl to no longer
> store any allocation data but read from the old gen allocation tracker
> instance.
>
> To answer the following questions from Thomas:
>> Quick(!) testing on the reproducer with the suggested patch showed around
> 23% of young gcs were evacuation failures
>
> The evacuation failures are "by design". The test case attached to the JBS bug
> intends to create a low pressure on the survive space and then suddenly
> increase the life cycle of objects in the Eden space to create a to-space
> exhaustion (I checked GC log, all evacuation failures are to-space
> exhaustions). This is the fastest approach I can come up with to get objects
> promoted to the old gen directly to trigger enough concurrent cycles for
> Adaptive IHOP to sample. Once Adaptive IHOP starts to predict, the to-space
> exhaustion is no longer needed. The evacuation failures are also observed in
> test run with Static IHOP. Why then are not observed without this fix? Because
> GC happens every 50 ms. Even during the allocation spike, only one region is
> filled up in Eden :)
>
>> but in return the change imho needs to provide some measure of the spikyness
> of the allocation between gcs. Otherwise G1 will run into to-space exhaustions
> and potentially full gcs all the time with such loads.
>
> I agree that the spikiness of the allocation between GCs should be considered
> and I understand your concern here. My fix might bring the old gen allocation
> rate too low that theoretically back-to-back full GC is possible. However, I
> was not able to create a test case to produce it as those short-live humongous
> objects are reclaimed so rapidly (my patch only accounts humongous objects
> that are allocated and reclaimed in the same allocation cycle). Could you give
> me some hint on how to produce the worst-case scenario?
>
> Tests:
> All hotspot tier-1 passed in fastdebug build.
>
Looks good, mostly some comments about code location/naming:
- g1Policy.cpp:60:
_ihop_control(create_ihop_control(&_old_gen_alloc_tracker, &_predictor)),
Please initialize the _old_gen_alloc_tracker before using it. Although
only the reference is passed, the constructor might do something with it
(in the future). Actually I remember that at some point MSVC complained
about such uses, but apparently does not any more, or it got more clever
about it.
- g1Policy.cpp:807:
please break the line after the first parameter so that the line isn't
that long.
- G1OldGenAllocationTracker: I dislike the use of "cycle" for the recent
mutator period. While the previous change introduced it, now that it is
used in a widespread way I would like this change to rename it. (GC)
"Cycle" is in G1 typically used for the time between young gen and the
next young gen after a marking, so this is confusing.
The time from one gc to the next gc also does not have any cyclical
behavior.
Something like "mutator_period" would imho be better, but it makes some
of the already long identifiers even longer. Maybe these can be
shortened a bit?
- in G1Policy::update_ihop_prediction() I would prefer if the
mutator_time_s parameter were either kept, or the
"_old_gen_alloc_tracker.last_cycle_duration() > min_valid_time"
condition moved into G1IHOPControl::update_allocation_info(). The reason
is that "cycle" is an already overloaded term and looks bad here. Maybe
this code will also improve if the above renaming of "cycle" mentioned
above would be done.
- Related to that I was wondering whether "last_cycle_duration" should
actually be placed into OldGenAllocTracker or not. I am kind of seeing
G1OldGenAllocationTracker as plain storage for just the byte sizes.
Also all the rates (and that member) are only used in G1IHOPControl
which indicates that maybe wrt to information hiding it and the uses of
it may be better located in G1IHOPControl (as it were)?
- new durations should be of type Tickspan, not double. This saves you
the "_s" (or whathever) suffix too.
- g1OldGenAllocationTracker.hpp:65 and 80: break the last line of the
comment paragraph again to avoid.
- the G1OldGenAllocationTracker simple doesn't need a "if (!UseG1GC"
guard as other g1 tests.
Looks good otherwise.
I will do some perf checking.
Thanks,
Thomas
More information about the hotspot-gc-dev
mailing list