[#18440] racc segv revisited — "Akinori MUSHA" <knu@...>

 次のバグの件なんですが、現時点では原因究明を含めて未解決という

24 messages 2002/10/02
[#18617] Re: racc segv revisited — "Akinori MUSHA" <knu@...> 2002/11/02

At Wed, 2 Oct 2002 23:19:59 +0900,

[ruby-dev:18487] Re: mem leak?

From: nobu.nakada@...
Date: 2002-10-10 13:30:31 UTC
List: ruby-dev #18487
なかだです。

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はできる。
    中田 伸悦

In This Thread