diff options
| author | Matt Valentine-House <matt@eightbitraptor.com> | 2026-03-31 13:05:25 +0100 |
|---|---|---|
| committer | Matt Valentine-House <matt@eightbitraptor.com> | 2026-04-09 13:24:09 +0100 |
| commit | a8009c9843dcbd742190700b59464e971236a55e (patch) | |
| tree | 157b5604e0b56fe6e6058cb3c759d046d1643db3 | |
| parent | 5c968c5078f87e539f72712fecefc61f53a6ff29 (diff) | |
Allow flex in heap growth threshold
Add a 7/8 multiplier to the min_free_slots checks in
gc_sweep_finish_heap and gc_marks_finish, allowing heaps to be up to
~12.5% below the free slots target without triggering a major GC or
forced growth.
With 12 heaps instead of 5, each heap independently hitting the exact
threshold would cause excessive memory growth. The slack prevents
cascading growth decisions while still ensuring heaps stay close to
their target occupancy.
| -rw-r--r-- | gc/default/default.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/gc/default/default.c b/gc/default/default.c index 5f008b44a1..7bad68f902 100644 --- a/gc/default/default.c +++ b/gc/default/default.c @@ -3870,7 +3870,8 @@ gc_sweep_finish_heap(rb_objspace_t *objspace, rb_heap_t *heap) heap_allocatable_bytes_expand(objspace, heap, swept_slots, heap->total_slots, heap->slot_size); } } - else if (objspace->heap_pages.allocatable_bytes < (min_free_slots - swept_slots) * heap->slot_size) { + else if (swept_slots < min_free_slots * 7 / 8 && + objspace->heap_pages.allocatable_bytes < (min_free_slots * 7 / 8 - swept_slots) * heap->slot_size) { gc_needs_major_flags |= GPR_FLAG_MAJOR_BY_NOFREE; heap->force_major_gc_count++; } @@ -5500,7 +5501,7 @@ gc_marks_finish(rb_objspace_t *objspace) } if (objspace->heap_pages.allocatable_bytes == 0 && sweep_slots < min_free_slots) { - if (!full_marking) { + if (!full_marking && sweep_slots < min_free_slots * 7 / 8) { if (objspace->profile.count - objspace->rgengc.last_major_gc < RVALUE_OLD_AGE) { full_marking = TRUE; } |
