まつもと ゆきひろです

とみたさんにもBCCしてます。

In message "[ruby-talk:11969] Ruby/MySql garbage collection problem"
    on 01/03/04, Eric Sven Ristad <ristad / mnemonic.com> writes:
|
|I've written a Ruby program that uses Tomita Masahiro's excellent
|ruby-mysql module to communicate with a MySql database.  Unfortunately
|if the program runs for a while, it runs out of memory and crashes.
|It looks like the problem is that the garbage collector is not getting
|called often enough to reclaim the results of the mysql queries made
|by my Ruby program.

Ruby/MySQLを使ってるとGCが呼ばれずプロセスが太るというレポートです。

たぶん、Ruby/MySQLがGCを呼ぶタイミングの問題なのだと思います。要するに
MySQL 自身が大量にmallocを使っても、Ruby側のオブジェクトがあまり生成さ
れないので、RubyのGCが起動されるのが遅れるということなのではないかと推
測します。

私はまだRuby/MySQLのソースを確認していないのですが、もしそれ自身にリー
クがないのであれば、resultのサイズの累計をとって、ある程度のサイズにな
れば明示的にGCを起動するとかが必要かもしれません。

|The following small program illustrates the problem:
|
|require "mysql"
|def leak(n,do_free)
|  db = Mysql.new("host",nil,nil,"test")
|  db.query("CREATE TEMPORARY TABLE RubyTest ( bogus INT NOT NULL )")
|  n.times{
|    result = db.query("SELECT bogus from RubyTest")
|    result.free if do_free
|  }
|  db.close
|end
|
|If I run leak(*,false) in irb then the amount of memory consumed by
|the irb process increases every time leak(*,false) is called.
|
|irb>				4.59M
|irb> load "leak.rb"		5.86M
|irb> leak(100,false)		6.69M
|irb> leak(1000,false)		15.0M
|irb> leak(10000,false)		19.2M
|
|But if I run leak(*,true) in irb then the amount of memory consumed by
|the irb process remains roughly constant.
|
|irb>				4.59M
|irb> load "leak.rb"		5.86M
|irb> leak(100,true)		5.94M
|irb> leak(1000,true)		5.94M
|irb> leak(10000,true)		5.94M
|
|Explicit calls to Mysqlres#free are ugly; I would much rather if the
|garbage collector did that work for me.  How can I make sure the
|garbage collector gets called before the process runs out of memory?
|
|Thanks,
|Eric