From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from kankan.nagaokaut.ac.jp (kankan.nagaokaut.ac.jp [133.44.2.24]) by blade.nagaokaut.ac.jp (8.12.3/8.12.3/Debian-6.6) with ESMTP id l8U4WRtv024307 for ; Sun, 30 Sep 2007 13:32:27 +0900 Received: from tonton.nagaokaut.ac.jp (tonton.nagaokaut.ac.jp [133.44.2.115]) by kankan.nagaokaut.ac.jp (Postfix) with ESMTP id 11C7974C1 for ; Sun, 30 Sep 2007 13:32:27 +0900 (JST) Received: from localhost (localhost.nagaokaut.ac.jp [127.0.0.1]) by tonton.nagaokaut.ac.jp (Postfix) with ESMTP id D7BFA15CCF for ; Sun, 30 Sep 2007 13:32:29 +0900 (JST) Received: from voscc.nagaokaut.ac.jp (voscc.nagaokaut.ac.jp [133.44.1.100]) by tonton.nagaokaut.ac.jp (Postfix) with ESMTP id 1D4C915CB8 for ; Sun, 30 Sep 2007 13:32:17 +0900 (JST) Received: from carbon.ruby-lang.org (carbon.ruby-lang.org [221.186.184.68]) by voscc.nagaokaut.ac.jp (Postfix) with ESMTP id 389D7630028 for ; Sun, 30 Sep 2007 13:32:14 +0900 (JST) Received: from beryllium.ruby-lang.org (beryllium.ruby-lang.org [127.0.0.1]) by carbon.ruby-lang.org (Postfix) with ESMTP id D74893C224CC6; Sun, 30 Sep 2007 13:32:03 +0900 (JST) Received: from mx1.aist.go.jp (mx1.aist.go.jp [150.29.246.133]) by carbon.ruby-lang.org (Postfix) with ESMTP id BFD0A3C224BA9 for ; Sun, 30 Sep 2007 13:31:52 +0900 (JST) Received: from rqsmtp2.aist.go.jp (rqsmtp2.aist.go.jp [150.29.254.123]) by mx1.aist.go.jp with ESMTP id l8U4VqqQ029944; Sun, 30 Sep 2007 13:31:52 +0900 (JST) env-from (akr@fsij.org) Received: from smtp4.aist.go.jp by rqsmtp2.aist.go.jp with ESMTP id l8U4VqWp026076; Sun, 30 Sep 2007 13:31:52 +0900 (JST) env-from (akr@fsij.org) Received: by smtp4.aist.go.jp with ESMTP id l8U4VpvI016760; Sun, 30 Sep 2007 13:31:51 +0900 (JST) env-from (akr@fsij.org) Delivered-To: ruby-core@ruby-lang.org Date: Sun, 30 Sep 2007 13:31:52 +0900 Posted: Sun, 30 Sep 2007 13:31:28 +0900 From: Tanaka Akira Reply-To: ruby-core@ruby-lang.org Subject: Re: gc.c -- possible logic error? To: ruby-core@ruby-lang.org Message-Id: <871wcgepu0.fsf@fsij.org> In-Reply-To: (Hugh Sasse's message of "Fri, 28 Sep 2007 21:57:22 +0900") References: X-ML-Name: ruby-core X-Mail-Count: 12301 X-MLServer: fml [fml 4.0.3 release (20011202/4.0.3)]; post only (only members can post) X-ML-Info: If you have a question, send e-mail with the body "help" (without quotes) to the address ruby-core-ctl@ruby-lang.org; help= User-Agent: T-gnus/6.15.7 (based on Oort Gnus v0.08) SEMI/1.14.6 (Maruoka) FLIM/1.14.6 (Marutamachi) APEL/10.6 Emacs/21.4 (i386-pc-linux-gnu) MULE/5.0 (SAKAKI) X-Spam-Checker-Version: SpamAssassin 3.1.7 (2006-10-05) on carbon.ruby-lang.org X-Spam-Level: X-Spam-Status: No, score=-4.9 required=7.0 tests=AWL,BAYES_00, CONTENT_TYPE_PRESENT,UNPARSEABLE_RELAY,UPPERCASE_25_50 autolearn=disabled version=3.1.7 X-Original-To: ruby-core@ruby-lang.org Mime-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") Content-Type: text/plain; charset=US-ASCII Precedence: bulk List-Id: ruby-core.ruby-lang.org List-Software: fml [fml 4.0.3 release (20011202/4.0.3)] List-Post: List-Owner: List-Help: List-Unsubscribe: X-Virus-Scanned: by amavisd 0.1 In article , Hugh Sasse writes: > I've been looking at Tom Copeland's memory allocation problem: > > http://tomcopeland.blogs.com/juniordeveloper/2007/09/tracking-down-a.html I think OpenStruct needs much more memory than Hash. It needs accessor methods for all member of all objects. I implemented ObjectSpace.count_objects to count objects. % ./ruby -rpp -e 'pp ObjectSpace.count_objects' {:T_ARRAY=>1261, :T_BIGNUM=>42, :T_CLASS=>418, :T_DATA=>297, :T_FILE=>5, :T_FLOAT=>6, :T_HASH=>3, :T_ICLASS=>21, :T_MATCH=>1, :T_MODULE=>18, :T_NODE=>10918, :T_OBJECT=>7, :T_REGEXP=>5, :T_STRING=>3101, :T_VALUES=>2, :freed=>11895} This means that there are 1261 arrays, etc. ObjectSpace.count_objects can be used to count objects required by Hash/OpenStruct. Hash: % ./ruby -e ' o = {} GC.start; c = ObjectSpace.count_objects 10.times {|i| o["foo#{i}"] = 1 GC.start; c2 = ObjectSpace.count_objects c.keys.each {|k| n = c2[k] - c[k]; print "#{k}:#{n} " if 0as.basic.flags) { + counts[BUILTIN_TYPE(p)]++; + } + else { + freed++; + } + } + } + + hash = rb_hash_new(); + rb_hash_aset(hash, ID2SYM(rb_intern("freed")), LONG2NUM(freed)); + for (i = 0; i <= T_MASK; i++) { + VALUE type; + switch (i) { + case T_NONE: type = ID2SYM(rb_intern("T_NONE")); break; + case T_NIL: type = ID2SYM(rb_intern("T_NIL")); break; + case T_OBJECT: type = ID2SYM(rb_intern("T_OBJECT")); break; + case T_CLASS: type = ID2SYM(rb_intern("T_CLASS")); break; + case T_ICLASS: type = ID2SYM(rb_intern("T_ICLASS")); break; + case T_MODULE: type = ID2SYM(rb_intern("T_MODULE")); break; + case T_FLOAT: type = ID2SYM(rb_intern("T_FLOAT")); break; + case T_STRING: type = ID2SYM(rb_intern("T_STRING")); break; + case T_REGEXP: type = ID2SYM(rb_intern("T_REGEXP")); break; + case T_ARRAY: type = ID2SYM(rb_intern("T_ARRAY")); break; + case T_FIXNUM: type = ID2SYM(rb_intern("T_FIXNUM")); break; + case T_HASH: type = ID2SYM(rb_intern("T_HASH")); break; + case T_STRUCT: type = ID2SYM(rb_intern("T_STRUCT")); break; + case T_BIGNUM: type = ID2SYM(rb_intern("T_BIGNUM")); break; + case T_FILE: type = ID2SYM(rb_intern("T_FILE")); break; + case T_TRUE: type = ID2SYM(rb_intern("T_TRUE")); break; + case T_FALSE: type = ID2SYM(rb_intern("T_FALSE")); break; + case T_DATA: type = ID2SYM(rb_intern("T_DATA")); break; + case T_MATCH: type = ID2SYM(rb_intern("T_MATCH")); break; + case T_SYMBOL: type = ID2SYM(rb_intern("T_SYMBOL")); break; + case T_VALUES: type = ID2SYM(rb_intern("T_VALUES")); break; + case T_BLOCK: type = ID2SYM(rb_intern("T_BLOCK")); break; + case T_UNDEF: type = ID2SYM(rb_intern("T_UNDEF")); break; + case T_NODE: type = ID2SYM(rb_intern("T_NODE")); break; + default: type = INT2NUM(i); break; + } + if (counts[i]) + rb_hash_aset(hash, type, LONG2NUM(counts[i])); + } + + return hash; +} + /* * The GC module provides an interface to Ruby's mark and * sweep garbage collection mechanism. Some of the underlying methods @@ -2190,4 +2254,6 @@ rb_define_method(rb_mKernel, "hash", rb_obj_id, 0); rb_define_method(rb_mKernel, "__id__", rb_obj_id, 0); rb_define_method(rb_mKernel, "object_id", rb_obj_id, 0); + + rb_define_module_function(rb_mObSpace, "count_objects", count_objects, 0); } -- Tanaka Akira