Only growth heaps are allowed to start major GCs. Before this patch,
growth heaps are defined as size pools that freed more slots than had
empty slots (i.e. there were more dead objects that empty space).

But if the size pool is relatively stable and tightly packed with mostly
old objects and has allocatable pages, then it would be incorrectly
classified as a growth heap and trigger major GC. But since it's stable,
it would not use any of the allocatable pages and forever be classified
as a growth heap, causing major GC thrashing. This commit changes the
definition of growth heap to require that the size pool to have no
allocatable pages.
This commit is contained in:
Peter Zhu 2022-06-08 11:05:53 -04:00
Родитель 08a6ec341e
Коммит 8d57336360
1 изменённых файлов: 5 добавлений и 3 удалений

8
gc.c
Просмотреть файл

@ -5684,9 +5684,11 @@ gc_sweep_finish_size_pool(rb_objspace_t *objspace, rb_size_pool_t *size_pool)
bool grow_heap = is_full_marking(objspace);
if (!is_full_marking(objspace)) {
/* The heap is a growth heap if it freed more slots than had empty slots. */
bool is_growth_heap = size_pool->empty_slots == 0 ||
size_pool->freed_slots > size_pool->empty_slots;
/* The heap is a growth heap if it freed more slots than had empty
* slots and used up all of its allocatable pages. */
bool is_growth_heap = (size_pool->empty_slots == 0 ||
size_pool->freed_slots > size_pool->empty_slots) &&
size_pool->allocatable_pages == 0;
if (objspace->profile.count - objspace->rgengc.last_major_gc < RVALUE_OLD_AGE) {
grow_heap = TRUE;