Bug #10431
Can't sweep garbage object immediatly when GC_ENABLE_LAZY_SWEEP=0
Description
GC_ENABLE_LAZY_SWEEP=0と設定してrubyをビルドし,以下のコードを
実行した場合,GC時にオブジェクトが解放されていないように見えます.
$ ../configure CFLAGS="-DGC_ENABLE_LAZY_SWEEP=0" && make miniruby $ cat bug2.rb GC.disable 10000.times { Object.new } total_freed_objects1 = GC.stat[:total_freed_objects] GC.enable GC.start(full_mark: true, immediate_sweep: true) total_freed_objects2 = GC.stat[:total_freed_objects] puts "freed object : #{total_freed_objects2 - total_freed_objects1}" $ ./miniruby -v ruby 2.2.0dev (2014-10-26 trunk 48073) [x86_64-darwin14] $ ./miniruby bug2.rb freed object : 0
また,rubyのコンパイルフラグをGC_ENABLE_LAZY_SWEEP=0,
RGENGC_CHECK_MODE=1と設定した上でビルドし,以下のコードを実行すると
assertで落ちます.
$ ./miniruby -e '10000.times { Object.new }' Assertion failed: (objspace->flags.stat == gc_stat_none), function gc_start, file ../gc.c, line 5802. [1] 91336 abort ./miniruby -e '10000.times { Object.new }'
sweepフェーズにてGC_ENABLE_LAZY_SWEEP!=1の時のみsweepが実行されるのが
原因のようですので,これを修正するパッチを作りました.
diff --git a/gc.c b/gc.c
index a27cc01..979e2e0 100644
--- a/gc.c
+++ b/gc.c
@@ -3314,9 +3314,8 @@ static void
gc_sweep_rest(rb_objspace_t *objspace)
{
rb_heap_t *heap = heap_eden; /* lazy sweep only for eden */
-
- if (is_lazy_sweeping(heap)) {
- while (is_lazy_sweeping(heap)) {
+ if ((heap)->sweep_pages != NULL) {
+ while ((heap)->sweep_pages != NULL) {
gc_sweep_step(objspace, heap);
}
}
English:
When I tried to compile ruby with GC_ENABLE_LAZY_SWEEP=0,
Ruby does not sweep objects immediatly.
$ ../configure CFLAGS="-DGC_ENABLE_LAZY_SWEEP=0" && make miniruby $ cat bug2.rb GC.disable 10000.times { Object.new } total_freed_objects1 = GC.stat[:total_freed_objects] GC.enable GC.start(full_mark: true, immediate_sweep: true) total_freed_objects2 = GC.stat[:total_freed_objects] puts "freed object : #{total_freed_objects2 - total_freed_objects1}" $ ./miniruby -v ruby 2.2.0dev (2014-10-26 trunk 48073) [x86_64-darwin14] $ ./miniruby bug2.rb freed object : 0
In addition, when I set GC_ENABLE_LAZY_SWEEP=0 and RGENGC_CHECK_MODE=1
ruby gives me assertion error like this:
$ ./miniruby -e '10000.times { Object.new }' Assertion failed: (objspace->flags.stat == gc_stat_none), function gc_start, file ../gc.c, line 5802. [1] 91336 abort ./miniruby -e '10000.times { Object.new }'
The following patch fix this problem.
diff --git a/gc.c b/gc.c
index a27cc01..979e2e0 100644
--- a/gc.c
+++ b/gc.c
@@ -3314,9 +3314,8 @@ static void
gc_sweep_rest(rb_objspace_t *objspace)
{
rb_heap_t *heap = heap_eden; /* lazy sweep only for eden */
-
- if (is_lazy_sweeping(heap)) {
- while (is_lazy_sweeping(heap)) {
+ if ((heap)->sweep_pages != NULL) {
+ while ((heap)->sweep_pages != NULL) {
gc_sweep_step(objspace, heap);
}
}
Associated revisions
gc.c: fix no lazy sweep mode
- gc.c (gc_sweep_rest): sweep rest pages regardless of whether lazy sweep is enabled or not. based on the patch by Masahiro Ide at [ruby-dev:48706]. [Bug #10431]
gc.c: fix no lazy sweep mode
- gc.c (gc_sweep_rest): sweep rest pages regardless of whether lazy sweep is enabled or not. based on the patch by Masahiro Ide at [ruby-dev:48706]. [Bug #10431]
gc.c: fix no lazy sweep mode
- gc.c (gc_sweep_rest): sweep rest pages regardless of whether lazy sweep is enabled or not. based on the patch by Masahiro Ide at [ruby-dev:48706]. [Bug #10431]
gc.c: fix no lazy sweep mode
- gc.c (gc_sweep_rest): sweep rest pages regardless of whether lazy sweep is enabled or not. based on the patch by Masahiro Ide at [ruby-dev:48706]. [Bug #10431]
gc.c: fix no lazy sweep mode
- gc.c (gc_sweep_rest): sweep rest pages regardless of whether lazy sweep is enabled or not. based on the patch by Masahiro Ide at [ruby-dev:48706]. [Bug #10431]
gc.c: fix no lazy sweep mode
- gc.c (gc_sweep_rest): sweep rest pages regardless of whether lazy sweep is enabled or not. based on the patch by Masahiro Ide at [ruby-dev:48706]. [Bug #10431]
History
Updated by nobu (Nobuyoshi Nakada) about 5 years ago
- Description updated (diff)
r41510でis_lazy_sweeping()を使うようになり、その後r47444でis_lazy_sweeping()が変更されたときの見落としのようです。
Updated by nobu (Nobuyoshi Nakada) about 5 years ago
- Backport changed from 2.0.0: UNKNOWN, 2.1: UNKNOWN to 2.0.0: DONTNEED, 2.1: DONTNEED
Updated by nobu (Nobuyoshi Nakada) about 5 years ago
- Status changed from Open to Closed
- % Done changed from 0 to 100
Applied in changeset r48150.
gc.c: fix no lazy sweep mode
- gc.c (gc_sweep_rest): sweep rest pages regardless of whether lazy sweep is enabled or not. based on the patch by Masahiro Ide at [ruby-dev:48706]. [Bug #10431]
gc.c: fix no lazy sweep mode
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48150 b2dd03c8-39d4-4d8f-98ff-823fe69b080e