Project

General

Profile

Backport #2367

Updated by jeremyevans0 (Jeremy Evans) over 4 years ago

=begin 
  
  遠藤です。 
 
  Class#dup がメモリリークするようです。 
  class C; end; loop { C.dup } で使用メモリが徐々に増えてきます。 
 
  object.c の init_copy と class.c の rb_mod_init_copy で RCLASS_IV_TBL を 
  二重に確保しているのと、古い RCLASS_M_TBL を解放していないことが原因の 
  ようです。 
 
  以下のパッチで直りますが、init_copy と rb_mod_init_copy の使い分けが良く 
  分からないので、正しいか分かりません。 
  変なことをしなければたぶん普通に動くと思うので (loop { C.dup } も変です 
  が) 、一旦コミットしようと思います。 
 
 
  diff --git a/class.c b/class.c 
  index a97494b..056e171 100644 
  --- a/class.c 
  +++ b/class.c 
  @@ -151,6 +151,9 @@ rb_mod_init_copy(VALUE clone, VALUE orig) 
       if (RCLASS_IV_TBL(orig)) { 
  	 ID id; 
 
  + 	 if (RCLASS_IV_TBL(clone)) { 
  + 	     st_free_table(RCLASS_IV_TBL(clone)); 
  + 	 } 
  	 RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(orig)); 
  	 CONST_ID(id, "__classpath__"); 
  	 st_delete(RCLASS_IV_TBL(clone), (st_data_t*)&id, 0); 
  @@ -159,6 +162,11 @@ rb_mod_init_copy(VALUE clone, VALUE orig) 
       } 
       if (RCLASS_M_TBL(orig)) { 
  	 struct clone_method_data data; 
  + 
  + 	 if (RCLASS_M_TBL(clone)) { 
  + 	     extern void rb_free_m_table(st_table *tbl); 
  + 	     rb_free_m_table(RCLASS_M_TBL(clone)); 
  + 	 } 
  	 data.tbl = RCLASS_M_TBL(clone) = st_init_numtable(); 
  	 data.klass = clone; 
  	 st_foreach(RCLASS_M_TBL(orig), clone_method, 
  diff --git a/gc.c b/gc.c 
  index f472bfc..9de079b 100644 
  --- a/gc.c 
  +++ b/gc.c 
  @@ -1459,8 +1459,8 @@ free_method_entry_i(ID key, rb_method_entry_t 
  *me, st_data_t data) 
       return ST_CONTINUE; 
   } 
 
  -static void 
  -free_m_table(st_table *tbl) 
  +void 
  +rb_free_m_table(st_table *tbl) 
   { 
       st_foreach(tbl, free_method_entry_i, 0); 
       st_free_table(tbl); 
  @@ -1988,7 +1988,7 @@ obj_free(rb_objspace_t *objspace, VALUE obj) 
         case T_MODULE: 
         case T_CLASS: 
  	 rb_clear_cache_by_class((VALUE)obj); 
  - 	 free_m_table(RCLASS_M_TBL(obj)); 
  + 	 rb_free_m_table(RCLASS_M_TBL(obj)); 
  	 if (RCLASS_IV_TBL(obj)) { 
  	     st_free_table(RCLASS_IV_TBL(obj)); 
  	 } 
 
  --  
  Yusuke ENDOH <mame@tsg.ne.jp> 
 
 =end 
 

Back