なかだです。

At Thu, 10 Oct 2002 20:59:32 +0900,
Tanaka Akira wrote:
> 生きているオブジェクトが占めるメモリ量の 2倍ということを意図しています。
> 
> ついでにいえば、生きているオブジェクトが占めるメモリ量は GC 直後に観測
> することを想定してます。

正確に計算するのは無理があるので、大雑把ですがこんなところでど
うでしょうか。[ruby-dev:18482]で試したところでは7MB弱になりまし
た。GCの速度がどの程度落ちるかは測ってみてませんが。


Index: gc.c =================================================================== RCS file: /cvs/ruby/src/ruby/gc.c,v retrieving revision 1.106 diff -u -2 -p -r1.106 gc.c --- gc.c 9 Oct 2002 06:12:54 -0000 1.106 +++ gc.c 10 Oct 2002 13:22:09 -0000 @@ -53,4 +53,14 @@ void *alloca (); #endif +#ifndef GC_MALLOC_LIMIT +#if defined(MSDOS) || defined(__human68k__) +#define GC_MALLOC_LIMIT 200000 +#else +#define GC_MALLOC_LIMIT 8000000 +#endif +#endif + +static unsigned long malloc_memories = 0; +static unsigned long malloc_limit = GC_MALLOC_LIMIT; static void run_final(); static VALUE nomem_error; @@ -79,5 +89,9 @@ ruby_xmalloc(size) } if (size == 0) size = 1; + malloc_memories += size; + if (malloc_memories > malloc_limit) { + rb_gc(); + } RUBY_CRITICAL(mem = malloc(size)); if (!mem) { @@ -116,4 +130,5 @@ ruby_xrealloc(ptr, size) if (!ptr) return xmalloc(size); if (size == 0) size = 1; + malloc_memories += size; RUBY_CRITICAL(mem = realloc(ptr, size)); if (!mem) { @@ -844,4 +859,13 @@ rb_gc_mark_children(ptr) static void obj_free _((VALUE)); +static int +size_of_table(tbl) + struct st_table *tbl; +{ + if (!tbl) return 0; + return tbl->num_bins * sizeof(struct st_table_entry *) + + tbl->num_entries * 4 * sizeof(VALUE); +} + static void gc_sweep() @@ -850,4 +874,5 @@ gc_sweep() int freed = 0; int i, j; + unsigned long live = 0; if (ruby_in_compile && ruby_parser_stack_on_heap()) { @@ -899,4 +924,30 @@ gc_sweep() else { RBASIC(p)->flags &= ~FL_MARK; + live += sizeof(VALUE); + switch (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; + } } p++; @@ -915,4 +966,6 @@ gc_sweep() } } + malloc_limit = live; + malloc_memories = 0; if (freed < FREE_MIN) { add_heap();
-- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦