RFR: Mixed evacuation [v6]
Kelvin Nilsen
kdnilsen at openjdk.java.net
Wed Apr 21 20:03:58 UTC 2021
On Tue, 20 Apr 2021 00:10:04 GMT, Kelvin Nilsen <kdnilsen at openjdk.org> wrote:
>> This code adds to generational Shenandoah the ability to perform concurrent garbage collection of young-gen and old-gen memory. Following completion of an old-gen concurrent marking effort, we select certain old-gen heap regions to serve as candidates for future collection sets. All dead objects within the old-gen heap regions that are not part of this candidate set are coalesced and filled so that remembered-set scanning of these old-gen heap regions will not be confused by "zombie objects" (objects that old-gen has decided are dead, which reside in regions that have not yet been collected). After concurrently coalescing and filling these dead objects, each subsequent young-gen evacuation pass includes a subset of the old-gen candidates until all candidates have been collected. This code passes TIER1 and hotspot-gc-shenandoah jtreg tests without regressions. A new jtreg test has been added to exercise concurrent old/young GC.
>
> Kelvin Nilsen has updated the pull request incrementally with one additional commit since the last revision:
>
> Change definition of CollectionThresholdGarbagePercent
>
> This is now defined to equal ShenandoahGarbageThreshold, which seems to have
> a default value of 25. The effect on running workloads is to choose more
> regions for the collection set than was observed with the previous
> configuration.
>
> Also addressed several improvements in white space and comments.
>
> The code now runs tier1 and hotspot_gc_shenandoah without regressions. It
> also succsessfully runs an Extremem stress test up until the point of
> failure due to triggering of full GC (after 113 completed GC passes, including
> two old-gen GC passes).
Thanks for the quick turnaround on this review. I will try to get through all these changes today.
Regarding the question of whether it makes sense to separate out the old-gen and new-gen heuristics, I think it very much makes sense to do so for the following reasons:
1. When properly configured, we expect the characteristic behaviors of young-gen and old-gen heaps to be very different. Young-gen heap normally has a high allocation rate and a high infant mortality rate, resulting in a relatively small percentage of total heap surviving each GC. In contrast, the old-gen heap typically has a relatively low allocation (promotion) rate, and no infant mortality rate. If we have properly configured the promotion heuristics, any object just promoted to old-gen has the same probability of becoming garbage on the next GC pass as any other object already existing in old-gen memory.
2. Eventually, we will expect old-gen heuristics to be a bit more sophisticated and deliberate in their analysis. In contrast, we expect young-gen to be fast and furious. For example, old-gen will probably want to bias collection set selection not only on which regions have highest percentage of garbage, but may also consider which regions have not been collected in a very long time. It is more likely that old-gen regions can sit and become stale. Not very likely this would ever happen in young-gen.
3. As currently implemented, the old-gen heuristics already need to keep track of additional information that is not relevant to young-gen collections, such as (a) which old-gen regions have been selected as candidates for future evacuations, (b) which old-gen regions need to be coalesced-and-filled so their memory is parseable by GC, and (c) how many previously selected candidates for collection have not yet been evacuated.
-------------
PR: https://git.openjdk.java.net/shenandoah/pull/29
More information about the shenandoah-dev
mailing list