Integrated: 8372543: Shenandoah: undercalculated the available size when soft max takes effect

Rui Li duke at openjdk.org
Tue Dec 16 07:05:03 UTC 2025


On Wed, 3 Dec 2025 02:02:18 GMT, Rui Li <duke at openjdk.org> wrote:

> Detailed math and repro see https://bugs.openjdk.org/browse/JDK-8372543. 
> 
> Currently in shenandoah, when deciding whether to have gc, how we calculate available size is:
> 
> 
> available = (Xmx * (100 - ShenandoahEvacReserve) / 100) - used
> soft_tail = Xmx - soft_max
> if (available - soft_tail < ShenandoahMinFreeThreshold * soft_max) // trigger gc 
> 
> 
> The if condition `available - soft_tail` will be reduced to: `-(ShenandoahEvacReserve/100) * Xmx - used + soft_max`, which means when soft max is the same, the larger Xmx is, the less free size the app would have and the more gc it would have, which does not make sense, especially for the case where the app is mostly idle. This caused one of our internal customers experienced frequent gc with minimal workload, when soft max heap size was set way lower than Xmx.
> 
> 
> Suggested fix: when deciding when to trigger gc, use logic similar to below:
> 
> mutator_soft_capacity = soft_max * (100 - ShenandoahEvacReserve) / 100;
> available = mutator_soft_capacity - used;
> if (available < mutator_soft_capacity) // trigger gc
> ``` 
> 
> Tests:
> - Ran the repro app `StableLiveSet.java` in https://bugs.openjdk.org/browse/JDK-8372543. Without fix, tip had ~2910 times gc in 20 sec with `-XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive -XX:SoftMaxHeapSize=512m -Xmx31g` jvm args. With the fix, only 18 times in 20 sec.
> - GHA passed.
> 
> -------
> This change also improved gc logging:
> 
> Before:
> 
> [6.831s][info][gc          ] Trigger: Free (52230K) is below minimum threshold (52428K)
> [6.831s][info][gc,free     ] Free: 1587M, Max: 1024K regular, 1539M humongous, Frag: 2% 
> external, 18% internal; Used: 352M, Mutator Free: 1940 Collector Reserve: 103M, Max: 1024K; Used: 0B
> 
> 
> After:
> 
> [8.358s][info][gc          ] Trigger: Free (Soft mutator free) (51498K) is below minimum threshold (52428K)
> [8.358s][info][gc,free     ] Whole heap stats: Total free: 1509M, Total used: 401M, Max free in a single region: 
> 1024K, Max humongous: 1490M; Frag stats: External: 0%, Internal: 21%;  Mutator freeset stats: Partition count: 
> 1911, Reserved: 1509M, Max free available in a single region: 1024K; Collector freeset stats: Partition count: 
> 122, Reserved: 102M, Max free available in a single region: 1024K;

This pull request has now been integrated.

Changeset: b1e8c4e0
Author:    Rui Li <ruiamzn at amazon.com>
Committer: Xiaolong Peng <xpeng at openjdk.org>
URL:       https://git.openjdk.org/jdk/commit/b1e8c4e030f42ea3146b2502c9ab030bc79a8147
Stats:     243 lines in 13 files changed: 152 ins; 61 del; 30 mod

8372543: Shenandoah: undercalculated the available size when soft max takes effect

Reviewed-by: wkemper, kdnilsen

-------------

PR: https://git.openjdk.org/jdk/pull/28622


More information about the hotspot-gc-dev mailing list