From: nobu.nakada@... Date: 2002-12-29T22:24:11+09:00 Subject: [ruby-dev:19236] Re: [1.8] speed なかだです。 At Sun, 29 Dec 2002 20:32:46 +0900, Yukihiro Matsumoto wrote: > |> これって具体的にはなにが起きてますか? > | > |ruby_xmalloc()でバッファを割り当てるときには、Object用であろう > |とそれ以外だろうとmalloc_increaseにサイズが加算されていきます。 > |一方で、malloc_limitはGCが理解できるObjectの使用している分しか > |計算されません。その結果、常にmalloc_increaseがmalloc_limitを上 > |回ることになってGCが動いてるんだろうという推測です。 > | > |これはどうすればいいのやら…。この方式はrealloc()でも不正確にな > |るし、止めたほうがいいのかも。 > > なるほどお。同意します、なくしましょう。 > > あれ、そういえば、わたし「この方式」を1.7でなくした覚えがあ > るんですが、なんで復活してるんだろう。 [ruby-dev:18482]です。ruby-talkでメモリが余ってるのに使ってない という話が出て、上限を上げるようにしたら今度はどんどん使いすぎ てしまうしってことです。 単純にオブジェクトの個数に比例させるようにしたほうが、 [ruby-dev:18482]は現状の倍弱、[ruby-talk:59662]は1.6の数%増し くらいで、それなりにバランスがとれてるように見えます。 Index: gc.c =================================================================== RCS file: /cvs/ruby/src/ruby/gc.c,v retrieving revision 1.113 diff -u -2 -p -r1.113 gc.c --- gc.c 4 Dec 2002 07:39:32 -0000 1.113 +++ gc.c 29 Dec 2002 13:11:04 -0000 @@ -880,5 +880,5 @@ gc_sweep() int freed = 0; int i, j; - unsigned long live = 0; + unsigned long live = 0, garbage = 0; if (ruby_in_compile && ruby_parser_stack_on_heap()) { @@ -902,5 +902,5 @@ gc_sweep() deferred_final_list = 0; for (i = 0; i < heaps_used; i++) { - int n = 0; + int n = 0, m = 0; RVALUE *free = freelist; RVALUE *final = final_list; @@ -930,30 +930,5 @@ gc_sweep() else { RBASIC(p)->flags &= ~FL_MARK; - live += sizeof(VALUE); - switch (BUILTIN_TYPE(p)) { - case T_OBJECT: - live += size_of_table(ROBJECT(p)->iv_tbl); - break; - case T_CLASS: - case T_ICLASS: - live += size_of_table(RCLASS(p)->iv_tbl); - live += size_of_table(RCLASS(p)->m_tbl); - break; - case T_STRING: - live += RSTRING(p)->len+1; - break; - case T_ARRAY: - live += RARRAY(p)->len * sizeof(VALUE); - break; - case T_HASH: - live += size_of_table(RHASH(p)->tbl); - break; - case T_BIGNUM: - live += RBIGNUM(p)->len * sizeof(BDIGIT); - break; - case T_STRUCT: - live += RSTRUCT(p)->len * sizeof(VALUE); - break; - } + live++; } p++; @@ -972,5 +947,7 @@ gc_sweep() } } - malloc_limit = live; + malloc_limit += malloc_increase; + malloc_limit *= (double)live / (live + freed); + if (malloc_limit < GC_MALLOC_LIMIT) malloc_limit = GC_MALLOC_LIMIT; malloc_increase = 0; if (freed < FREE_MIN) { -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦