[前][次][番号順一覧][スレッド一覧]

ruby-changes:72100

From: Peter <ko1@a...>
Date: Thu, 9 Jun 2022 01:09:39 +0900 (JST)
Subject: [ruby-changes:72100] 8d57336360 (master): Fix major GC thrashing

https://git.ruby-lang.org/ruby.git/commit/?id=8d57336360

From 8d57336360497e94403a71bd13de8faa76f1dbcb Mon Sep 17 00:00:00 2001
From: Peter Zhu <peter@p...>
Date: Wed, 8 Jun 2022 11:05:53 -0400
Subject: Fix major GC thrashing

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.
---
 gc.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/gc.c b/gc.c
index 42e0da8d09..42ccae0d11 100644
--- a/gc.c
+++ b/gc.c
@@ -5684,9 +5684,11 @@ gc_sweep_finish_size_pool(rb_objspace_t *objspace, rb_size_pool_t *size_pool) https://github.com/ruby/ruby/blob/trunk/gc.c#L5684
         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;
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]