GC issues

$B!!$5$5$@$G$9!#(B

$B!!(BGC $B$^$o$j$r8+$F$?$s$G$9$,!"$$$/$D$+5?LdE@$,$"$j$^$7$?!#(B

  1. $B%U%!%$%J%i%$%6$N5/F0%?%$%_%s%0(B

$B!!8=:!"%U%!%$%J%i%$%6$O(B after_gc_sweep()
$B$N%?%$%
%s%0$G$7$+5/F0$5$l$^$;(B
$B$s!#$D$^$j!"$9$Y$F$N(B sweep
$B$,40N;$9$k$^$GCY1d$9$k$o$1$G$9$,!"$3$l$O;q8;(B
$B2rJ|$N%?%$%_%s%0$rCY$/$9$k$3$H$K$J$k$N$G!"$^$:$$$h$&$J5$$,$7$^$9!#(B

$B!!$3$l$r!"(Bslot_sweep
$B$N$?$S$K%U%!%$%J%i%$%6$r8F$V$h$&$K$7$?$i!"%a%b%j$,(B
$B>/$J$$4D6-$G$b!"(Btest-all $B$,:G8e$^$GF0$/$h$&$K$J$j$^$7$?!#(B

  1. GC.stress $B$,(B true $B;~$N5sF0(B

$B!!(BGC.stress $B$,(B true $B$N;~$O!"(Bmark/free
$B$r9T$$!"%*%V%8%’%/%H6u4V$,!J$=$l$J(B
$B$j$K!Ke:No$K$J$C$F$$$k!"$H$$$&$3$H$r4|BT$7$F$$$k$h$&$K;W$$$^$9$,!“8=:_$O(B
gc_lazy_sweep() $B$r9T$&$@$1$J$N$G!”$^$@(B sweep
$B$,40N;$7$F$$$J$$>l9g$O!"(B
mark $B$J$I$O5/$3$j$^$;$s!#(B

$B!!$H$j$"$($:(B 1 $B$OLdBj$@$m$&$H;W$$$^$9!#(B

$B!!$"$H!"=t!98+$F$$$C$?7k2L$N%Q%C%A!#(B

Index: gc.c

— gc.c (revision 29675)
+++ gc.c (working copy)
@@ -1043,12 +1043,25 @@ rb_during_gc(void)

#define RANY(o) ((RVALUE*)(o))

-static VALUE
-rb_newobj_from_heap(rb_objspace_t *objspace)
+VALUE
+rb_newobj(void)
{

  • rb_objspace_t *objspace = &rb_objspace;
    VALUE obj;
  • if ((ruby_gc_stress && !ruby_disable_gc_stress) || !freelist) {
  • if (during_gc) {
  • dont_gc = 1;
  • during_gc = 0;
  • rb_bug(“object allocation during garbage collection phase”);
  • }
  • if (ruby_gc_stress && !ruby_disable_gc_stress) {
  • if (!garbage_collect(objspace)) {
  •  during_gc = 0;
    
  •  rb_memerror();
    
  • }
  • }
  • if (!freelist) {
    if (!gc_lazy_sweep(objspace)) {
    during_gc = 0;
    rb_memerror();
    @@ -1068,20 +1081,6 @@ rb_newobj_from_heap(rb_objspace_t *objsp
    return obj;
    }

-VALUE
-rb_newobj(void)
-{

  • rb_objspace_t *objspace = &rb_objspace;
  • if (during_gc) {
  • dont_gc = 1;
  • during_gc = 0;
  • rb_bug(“object allocation during garbage collection phase”);
  • }
  • return rb_newobj_from_heap(objspace);
    -}

NODE*
rb_node_newnode(enum node_type type, VALUE a0, VALUE a1, VALUE a2)
{
@@ -1947,6 +1946,11 @@ slot_sweep(rb_objspace_t *objspace, stru
objspace->heap.free_num += free_num;
}
objspace->heap.final_num += final_num;
+

  • if (final_num > 0) {
  • /* kick finalizer */
  • RUBY_VM_SET_FINALIZER_INTERRUPT(GET_THREAD());
  • }
    }

static int
@@ -1976,6 +1980,11 @@ before_gc_sweep(rb_objspace_t *objspace)
}
objspace->heap.sweep_slots = heaps;
objspace->heap.free_num = 0;
+

  • /* sweep unlinked method entries */
  • if (GET_VM()->unlinked_method_entry_list) {
  • rb_sweep_method_entry(GET_VM());
  • }
    }

static void
@@ -1995,20 +2004,9 @@ after_gc_sweep(rb_objspace_t *objspace)
}
malloc_increase = 0;

  • if (deferred_final_list) {

  •    /* clear finalization list */
    
  • RUBY_VM_SET_FINALIZER_INTERRUPT(GET_THREAD());

  • }

  • else{
    free_unused_heaps(objspace);
    }

  • /* sweep unlinked method entries */

  • if (th->vm->unlinked_method_entry_list) {

  • rb_sweep_method_entry(th->vm);

  • }
    -}

static int
lazy_sweep(rb_objspace_t *objspace)
{
@@ -2785,17 +2783,20 @@ run_single_final(VALUE arg)
}

static void
-run_finalizer(rb_objspace_t *objspace, VALUE obj, VALUE objid, VALUE
table)
+run_finalizer(rb_objspace_t *objspace, VALUE objid, VALUE table)
{
long i;
int status;
VALUE args[3];

  • args[1] = 0;
  • args[2] = (VALUE)rb_safe_level();
  • if (!args[1] && RARRAY_LEN(table) > 0) {
  • if (RARRAY_LEN(table) > 0) {
    args[1] = rb_obj_freeze(rb_ary_new3(1, objid));
    }

  • else {

  • args[1] = 0;

  • }

  • args[2] = (VALUE)rb_safe_level();
    for (i=0; i<RARRAY_LEN(table); i++) {
    VALUE final = RARRAY_PTR(table)[i];
    args[0] = RARRAY_PTR(final)[1];
    @@ -2828,7 +2829,7 @@ run_final(rb_objspace_t *objspace, VALUE

    key = (st_data_t)obj;
    if (st_delete(finalizer_table, &key, &table)) {

  • run_finalizer(objspace, obj, objid, (VALUE)table);
  • run_finalizer(objspace, objid, (VALUE)table);
    }
    }

@@ -2843,17 +2844,10 @@ finalize_deferred(rb_objspace_t *objspac
}
}

-static void
-gc_finalize_deferred(rb_objspace_t *objspace)
-{

  • finalize_deferred(objspace);
  • free_unused_heaps(objspace);
    -}

void
rb_gc_finalize_deferred(void)
{

  • gc_finalize_deferred(&rb_objspace);
  • finalize_deferred(&rb_objspace);
    }

static int
@@ -2919,7 +2913,7 @@ rb_objspace_call_finalizer(rb_objspace_t
st_foreach(finalizer_table, force_chain_object, (st_data_t)&list);
while (list) {
struct force_finalize_list *curr = list;

  •  run_finalizer(objspace, curr->obj, rb_obj_id(curr->obj), 
    

curr->table);

  •  run_finalizer(objspace, rb_obj_id(curr->obj), curr->table);
     st_delete(finalizer_table, (st_data_t*)&curr->obj, 0);
     list = curr->next;
     xfree(curr);
    

@@ -2973,7 +2967,8 @@ rb_gc(void)
{
rb_objspace_t *objspace = &rb_objspace;
garbage_collect(objspace);

  • gc_finalize_deferred(objspace);
  • finalize_deferred(objspace);
  • free_unused_heaps(objspace);
    }

/*

$B!!8+$J$,$i%a%b$C$F$$$C$?$b$N!#;w$?$h$&$J4X?t$,$"$C$F!"$A$g$C$H$o$+$i$J$/(B
$B$J$C$?$N$G@0M}!#(B

slot_sweep(rb_objspace_t *objspace, struct heaps_slot *sweep_slot)
$B$"$k%9%m%C%H$K$D$$$F!"(Bsweep $B$r9T$&!#(Bsweep_slot
$B$K$"$C$?$b$N$r<h$C$F$/$k!#(B

ready_to_gc(rb_objspace_t *objspace)
GC $B$r$d$C$FNI$1$l$P!J(Bdont_gc || during_gc$B!K(BTRUE $B$rJV$9(B
$B$b$7!"$d$C$A$cBLL$G(B freelist $B$,(B 0 $B$J$i!"(Bheaps
$B$r3HD%$7$FBP1~!#(B

before_gc_sweep(rb_objspace_t *objspace)
mark $B=*N;8e!"(Bsweep $B$r3+;O$9$kA0=hM}!#(B

after_gc_sweep(rb_objspace_t *objspace)
sweep $B=*N;8e$N8e=hM}!#(B

lazy_sweep(rb_objspace_t *objspace)
freelist $B$K2?$+$7$i$NCM$,F~$k$^$G!"(Blazy sweep $B$r?J$a$k!#(B
$B?J$a$F$b!"(Bfreelist $B$KCM$,F~$C$F$$$J$1$l$P!"(BFALSE $B$rJV$9!#(B

rest_sweep(rb_objspace_t *objspace)
$B$^$@(B sweep $B$7$F$$$J$$(B slot $B$,;D$C$F$$$l$P!"$=$l$r$9$Y$F(B
sweep $B$9$k!#(B

gc_lazy_sweep(rb_objspace_t *objspace)
Lazy sweep $BHG(B garbage_collect
newobj $B$O!"$3$N4X?t$r8F$V(B

  • $B$b$7!"(Bsweep $B$NESCf$G$"$l$P!"(Blazy_sweep() $B$9$k(B
    freelist $B$,Kd$^$l$P!"$=$3$GJV$9(B
  • mark $B$r$9$k(B
  • $B:G=i$N(B1$B8D$N%*%V%8%’%/%H$,8+$D$+$k$^$G!"(Bsweep $B$r$9$k(B
    $B$_$D$+$C$?;~E@$G!"(Bsweep $BCfCG(B

gc_sweep(rb_objspace_t *objspace)
$BA4It(B sweep $B$9$k(B


finalize_list(rb_objspace_t *objspace, RVALUE *p)
p $B$O(B RVALUE $B$NO"7k%j%9%H!#$3$N%j%9%H$O%U%!%$%J%i%$%6BP>]!#(B

run_final(rb_objspace_t *objspace, VALUE obj)
obj $B$N8e;OKv$r9T$&(B

  • T_DATA $B$N>l9g$OEPO?$5$l$?(B free $B4X?t$r8F$V(B
  • Ruy
    $B%l%Y%k$G%U%!%$%J%i%$%6$,EPO?$5$l$F$$$l$P!"$=$l$r8F$V!J(Brun_finalizer$B!K(B

run_finalizer(rb_objspace_t *objspace, VALUE obj, VALUE objid, VALUE
table)
Ruby $B%l%Y%k$GEPO?$5$l$?%U%!%$%J%i%$%6$r5/F0$9$k(B

  • $B%U%!%$%J%i%$%6$OJ#?tEPO?$5$l$F$$$k$+$b!#$=$l$,(B talbe
    $B$H$$$&G[Ns!#(B
  • $B$3$l!"(Bobj $BMW$i$J$$$8$c$s!#(B
  • table $B$C$F4X?tL>$OJQ$J46$8!#(B

run_single_final(VALUE arg)
$B%U%!%$%J%i%$%6$r0l$D5/F0$9$k!#(Brun_finalizer$B$+$i!"(Brb_protec
$B$G8F$P$l$k!#(B

finalize_deferred(rb_objspace_t *objspace)
$BCY1d$5$l$?%U%!%$%J%i%$%6$r5/F0$9$k!#(B

  • deferred_final_list $B$G<($5$l$kO"7k%j%9%H(B
  • $B5/F0$9$kA0$K!"(Bdeferred_final_list $B$r%/%j%"(B

gc_finalize_deferred(rb_objspace_t *objspace)
$B%U%!%$%J%i%$%6$r8F$s$G!"$=$N8e;H$o$l$F$$$J$$%R!<%W$r2s<}!#(B

  • finalize_deferred(objspace);
  • free_unused_heaps(objspace);
    $BF1$8$h$&$J$3$H4X?t$,B?$$$N$G!"$3$l$OGQ;_$7$?$[$&$,NI$5$=$&!#(B

rb_gc_finalize_deferred(void)
gc_finalize_deferred $B$r!"(Bgc.c $B$+$i8F$V$?$a$N%$%s%?!<%U%’!<%9!#(B
thread.c $B$G!"3d$j9~$_=hM}$N$H$3$m$+$i;H$o$l$F$$$k!#(B

  • free_unused_heaps $B$O8F$P$J$/$F$$$$$s$G$O$J$$$+!)(B
    $B$D$^$j!"(Bafter_gc_sweep $B$@$1$G8F$Y$P$$$$$H;W$o$l$k!#(B

(2010/11/03 8:59), SASADA Koichi wrote:

$B!!8=:!"%U%!%$%J%i%$%6$O(B after_gc_sweep() $B$N%?%$%%s%0$G$7$+5/F0$5$l$^$;(B
$B$s!#$D$^$j!"$9$Y$F$N(B sweep $B$,40N;$9$k$^$GCY1d$9$k$o$1$G$9$,!"$3$l$O;q8;(B
$B2rJ|$N%?%$%_%s%0$rCY$/$9$k$3$H$K$J$k$N$G!"$^$:$$$h$&$J5$$,$7$^$9!#(B

$B!!4V0c$$!#<!$N(B GC $B$N5/F0%?%$%_%s%0$^$GCY1d!"$G$7$?!#(B

$B$^$D$b$H(B $B$f$-$R$m$G$9(B

In message “Re: [ruby-dev:42532] Re: GC issues”
on Thu, 4 Nov 2010 09:52:33 +0900, Narihiro N.
[email protected] writes:

|> GC $B$^$o$j$r8+$F$?$s$G$9$,!“$$$/$D$+5?LdE@$,$”$j$^$7$?!#(B
|>
|> 1. $B%U%!%$%J%i%$%6$N5/F0%?%$%%s%0(B
|>
|> $B8=:
!“%U%!%$%J%i%$%6$O(B after_gc_sweep() $B$N%?%$%%s%0$G$7$+5/F0$5$l$^$;(B
|> $B$s!#$D$^$j!“$9$Y$F$N(B sweep $B$,40N;$9$k$^$GCY1d$9$k$o$1$G$9$,!”$3$l$O;q8;(B
|> $B2rJ|$N%?%$%
%s%0$rCY$/$9$k$3$H$K$J$k$N$G!”$^$:$$$h$&$J5$$,$7$^$9!#(B
|>
|> $B$3$l$r!“(Bslot_sweep $B$N$?$S$K%U%!%$%J%i%$%6$r8F$V$h$&$K$7$?$i!”%a%b%j$,(B
|> $B>/$J$$4D6-$G$b!"(Btest-all $B$,:G8e$^$GF0$/$h$&$K$J$j$^$7$?!#(B
|>
|
|$B%Q%C%A$r8+$^$7$?!#;d$OLdBj$J$$$H;W$$$^$9!#(B

$B$8$c$“!”$5$5$@$5$s!"%3%_%C%H$7$F$/$@$5$$!#(B

nari$B$G$9!#(B

2010$BG/(B11$B7n(B3$BF|(B17:59 SASADA Koichi [email protected]:

$B$3$l$r!“(Bslot_sweep $B$N$?$S$K%U%!%$%J%i%$%6$r8F$V$h$&$K$7$?$i!”%a%b%j$,(B
$B>/$J$$4D6-$G$b!"(Btest-all $B$,:G8e$^$GF0$/$h$&$K$J$j$^$7$?!#(B

$B%Q%C%A$r8+$^$7$?!#;d$OLdBj$J$$$H;W$$$^$9!#(B

  1. GC.stress $B$,(B true $B;~$N5sF0(B

GC.stress $B$,(B true $B$N;~$O!“(Bmark/free
$B$r9T$$!”%*%V%8%'%/%H6u4V$,!J$=$l$J(B
$B$j$K!Ke:No$K$J$C$F$$$k!“$H$$$&$3$H$r4|BT$7$F$$$k$h$&$K;W$$$^$9$,!“8=:_$O(B
gc_lazy_sweep() $B$r9T$&$@$1$J$N$G!”$^$@(B sweep $B$,40N;$7$F$$$J$$>l9g$O!”(B
mark $B$J$I$O5/$3$j$^$;$s!#(B

$BC1=c$K(B GC.stress $B$O(BGC$B$KIi2Y$r$+$1$k$b$N$@$H;W$C$F!"Kh2s(B
gc_lazy_sweep()
$B$r8F$S=P$9$h$&$K$7$F$$$^$7$?!#(B
$BFC$K?<$$0U?^$O$J$$$N$G!"0[O@$,$J$1$l$PA0$HF1$8$h$&$K(B
garbage_collect()
$B$r8F$S=P$9$h$&$KLa$7$F$*$-$^$9!#(B

(2010/11/04 3:05), Yukihiro M. wrote:

|>
|
|$B%Q%C%A$r8+$^$7$?!#;d$OLdBj$J$$$H;W$$$^$9!#(B

$B$8$c$"!"$5$5$@$5$s!"%3%_%C%H$7$F$/$@$5$$!#(B

$B!!$H$N$3$H$J$N$G$9$,!"<j85$N4D6-$G!“5U$K%a%b%j$,B-$j$J$$!”$H$$$&>u67$,H/(B
$B@8$7$F$$$^$9!J4QB,$9$k$H!"%a%b%j$O4V$K9g$C$F$$$k$h$&$J5$$,$9$k$N$@$1$I!"(B
ENOMEM
$B$,BgNLH/@8!K!#$A$g$C$H!"$J$<5/$3$C$F$$$k$N$+$o$+$i$J$$>u67$G$7(B
$B$F!“C/$+!”%a%b%j$,>/$J$$4D6-$GDI;n$7$FD4$Y$FLc$($k$H$$$$$J$H;W$&$N$G$9$,!#(B

$B!!$5$5$@$G$9!#(B

(2010/11/04 0:52), Narihiro N. wrote:

  1. GC.stress $B$,(B true $B;~$N5sF0(B

GC.stress $B$,(B true $B$N;~$O!"(Bmark/free
$B$r9T$$!"%*%V%8%’%/%H6u4V$,!J$=$l$J(B

$B$j$K!Ke:No$K$J$C$F$$$k!"$H$$$&$3$H$r4|BT$7$F$$$k$h$&$K;W$$$^$9$,!“8=:_$O(B
gc_lazy_sweep() $B$r9T$&$@$1$J$N$G!”$^$@(B sweep $B$,40N;$7$F$$$J$$>l9g$O!"(B
mark $B$J$I$O5/$3$j$^$;$s!#(B
$BC1=c$K(B GC.stress $B$O(BGC$B$KIi2Y$r$+$1$k$b$N$@$H;W$C$F!"Kh2s(B
gc_lazy_sweep()
$B$r8F$S=P$9$h$&$K$7$F$$$^$7$?!#(B
$BFC$K?<$$0U?^$O$J$$$N$G!"0[O@$,$J$1$l$PA0$HF1$8$h$&$K(B garbage_collect()
$B$r8F$S=P$9$h$&$KLa$7$F$*$-$^$9!#(B

$B!!$3$l$,F3F~$5$l$?7P0^$O!"(BC $B3HD%$G(B volatile
$BH4$1$J$I$G!“4V0c$($F(B GC $B$G2s(B
$B<}$5$l$F$7$^$&$h$&$J%*%V%8%’%/%H$rH/8+$7$d$9$/$9$k$?$a!”$J$k$Y$/Aa$/!&B?(B
$B$/(B mark $B$9$k$3$H$G8+$D$1$h$&!"$C$F$3$H$@$C$?$H;W$$$^$9!#(B

$B!!$J$N$G!"8=>u$G$O$=$N0UL#$,$J$/$J$C$F$$$^$9!#(B

stress $B$C$FL>A0$,NI$/$J$$!)(B