From: Masao M. <mu...@hi...> - 2003-10-03 17:04:22
|
むとうです。 質問です。 [ 814787 ] Memory leak in Gdk::Pixbuf http://sourceforge.net/tracker/index.php?func=detail&aid=814787&group_id=53614&atid=470969 の件で、確認をしているのですが、 確かに上記にあるサンプルを動かすと画面が固まります。 でも、GC.startを入れれば正常に動作します。 #!/usr/bin/env/ruby require 'gnome2' Gtk.init app = Gtk::Window.new img = Gtk::Image.new app.add img.show app.show file = ARGV[0] Thread.new do 300.times do pb = Gdk::Pixbuf.new(file) img.pixbuf = pb GC.start #p pb.ref_count #(1) end end Gtk.main で、これの考え方なんですが、 「GC.startをすればメモリリークが起きないのであれば Ruby-GNOME2としては問題ない」 と考えて良いのですかね? あと、(1)でref_countの値が2のままだと指摘されて ますが(たぶん)、これは、 img.pixbuf = pb で + 1される pb.ref_countのGOBJ2RVALで+1される から、2で問題ないですよね? この辺りになるととたんに自信がなくなるむとうでした。 #今日のワンコ風 -- .:% Masao Mutoh<mu...@hi...> |
From: Hiroshi I. <ig...@ru...> - 2003-10-04 12:48:46
|
いがらしです。 At Sat, 4 Oct 2003 02:04:17 +0900, Masao Mutoh <mu...@hi...> wrote: > > [ 814787 ] Memory leak in Gdk::Pixbuf > http://sourceforge.net/tracker/index.php?func=detail&aid=814787&group_id=53614&atid=470969 > > の件で、確認をしているのですが、 > 確かに上記にあるサンプルを動かすと画面が固まります。 > > でも、GC.startを入れれば正常に動作します。 いまはobsoleteなGdk::Imlibでも同じ問題がありました。 http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-ext/1630 まさ私のやり残しですね。ごめんなさい。 ruby-gnomeのGdk::Imlib#renderでは、こんな風に 外部ライブラリが内部である程度メモリを使ったであろう時点で 明示的にGCを起動しています。rb_gdkimlib_render_limitを いくつにすればいいのかというのが難しいんですが。 render_count += FIX2INT(w) * FIX2INT(h); if(render_count > rb_gdkimlib_render_limit){ rb_gc(); render_count = 0; } > で、これの考え方なんですが、 > > 「GC.startをすればメモリリークが起きないのであれば > Ruby-GNOME2としては問題ない」 > > と考えて良いのですかね? そうですねぇ。でもそれなりにコストの大きいGCを 起動したくないという場面もあるかも。画像以外にも たくさんオブジェクトがいるときとか。 IO#closeのように明示的にリソース解放できるのが 一番いいかと思うのですが、Gdk::Pixbuf#destroy なんていうのはないんですよね。Cレベルでは あるのかは調べてません。 > あと、(1)でref_countの値が2のままだと指摘されて > ますが(たぶん)、これは、 > img.pixbuf = pb で + 1される > pb.ref_countのGOBJ2RVALで+1される > から、2で問題ないですよね? たぶん。 -- 五十嵐 宏 (Hiroshi IGARASHI) |
[ruby-gnome2-devel-ja] Re: [ruby-gnome2-devel-ja]
=?iso-2022-jp?B?R0MbJEIkSyREJCQkRiROPEFMZBsoQg==?=
From: Masahiro S. ()
<sa...@to...> - 2003-10-04 18:05:36
|
さかいです。 From: Masao Mutoh <mu...@hi...> Subject: [ruby-gnome2-devel-ja] GCについての質問 Date: Sat, 4 Oct 2003 02:04:17 +0900 > むとうです。 > 「GC.startをすればメモリリークが起きないのであれば > Ruby-GNOME2としては問題ない」 > > と考えて良いのですかね? そう思います。 > あと、(1)でref_countの値が2のままだと指摘されて > ますが(たぶん)、これは、 > img.pixbuf = pb で + 1される > pb.ref_countのGOBJ2RVALで+1される > から、2で問題ないですよね? 2で問題ないです。 # pb = Gdk::Pixbuf.new(file) でオブジェクトが作られた時点で1、 # img.pixbuf = pb で + 1 されて 2 ですね。 # pb.ref_count では、Ruby側のオブジェクトが既に存在しているので、 # GOBJ2RVALはリファレンスカウンタを増やさないはずです。 -- 酒井 政裕 / Masahiro Sakai |
[ruby-gnome2-devel-ja] Re: [ruby-gnome2-devel-ja]
=?iso-2022-jp?B?R0MbJEIkSyREJCQkRiROPEFMZBsoQg==?=
From: Masahiro S. ()
<sa...@to...> - 2003-10-04 18:31:49
Attachments:
glib.diff
|
さかいです。 From: Hiroshi IGARASHI <ig...@ru...> Subject: Re: [ruby-gnome2-devel-ja] GCについての質問 Date: Sat, 04 Oct 2003 21:48:40 +0900 > いがらしです。 > > At Sat, 4 Oct 2003 02:04:17 +0900, > Masao Mutoh <mu...@hi...> wrote: > > > > [ 814787 ] Memory leak in Gdk::Pixbuf > > http://sourceforge.net/tracker/index.php?func=detail&aid=814787&group_id=53614&atid=470969 > > > > の件で、確認をしているのですが、 > > 確かに上記にあるサンプルを動かすと画面が固まります。 > > > > でも、GC.startを入れれば正常に動作します。 > > いまはobsoleteなGdk::Imlibでも同じ問題がありました。 > http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-ext/1630 > まさ私のやり残しですね。ごめんなさい。 なるほど、そういう問題でしたか。 > ruby-gnomeのGdk::Imlib#renderでは、こんな風に > 外部ライブラリが内部である程度メモリを使ったであろう時点で > 明示的にGCを起動しています。rb_gdkimlib_render_limitを > いくつにすればいいのかというのが難しいんですが。 > > render_count += FIX2INT(w) * FIX2INT(h); > if(render_count > rb_gdkimlib_render_limit){ > rb_gc(); > render_count = 0; > } そういえば、g_mem_set_vtable()を使って、 glibのメモリ管理そのものを置き換えてしまうという手も 使えるかも知れません。 -- 酒井 政裕 / Masahiro Sakai |
From: Masao M. <mu...@hi...> - 2003-10-05 08:49:18
|
むとうです。 On Sun, 05 Oct 2003 10:14:22 +0900 Hiroshi IGARASHI <ig...@ru...> wrote: > いがらしです。 > > At Sun, 05 Oct 2003 03:30:53 +0900 (JST), > Masahiro Sakai (酒井政裕) <sa...@to...> wrote: > > > > そういえば、g_mem_set_vtable()を使って、 > > glibのメモリ管理そのものを置き換えてしまうという手も > > 使えるかも知れません。 これ、良いですね。まずはこれあてちゃってください。 実際、試してみたんですけど、前回は”固まった”ものが、 ひととおり最後までは処理できます。 もちろん、メモリの限界(?)までGCされないので、 GC.startを明示的に行うよりは重くなります。ま、当たり前ですね。 > これができるなら、同プロセス内のglib管理下のメモリに > 関しては解決できるでしょうね。ただこれ以外にも > > ・メモリ以外のリソース(File Descriptorなど) > ・他プロセス(ex. Xサーバ)側のリソース > > があって、 > > ・オブジェクト生成時の救済 > (リソースが足りなかったらrb_gc()を呼んでから再試行。 > ex. rubyのio.c, socket.c) rb_fopen()等を見てみたのですが、それを参考にするとしたら オブジェクト生成時の救済はGdk::Pixbuf.new内のgdk_pixbuf_new()がNULL を返したらrb_gc()を入れて再度gdk_pixbuf_new()してみれば良いのかな。 > ・明示的なリソース解放手段の提供 gtk_object_destroy()の中身ってg_object_run_dispose()呼んでる だけなんですね。これを実装すれば良いのかな。 ってやってみたら、イマイチ効果がわかりませんでした。 オブジェクトはきちんとdestroyedになるようだけど。 rb_gc()との合わせ技だとかなり効果的ですがどうでしょうか。 サンプル require 'gnome2' Gtk.init app = Gtk::Window.new img = Gtk::Image.new app.add img.show app.show file = ARGV[0] Thread.new do 300.times do pb = Gdk::Pixbuf.new(file) img.pixbuf = pb pb.run_dispose p pb, i end end Gtk.main Index: rbgobj_object.c =================================================================== RCS file: /cvsroot/ruby-gnome2/ruby-gnome2/glib/src/rbgobj_object.c,v retrieving revision 1.52 diff -u -r1.52 rbgobj_object.c --- rbgobj_object.c 3 Sep 2003 07:11:02 -0000 1.52 +++ rbgobj_object.c 5 Oct 2003 08:46:57 -0000 @@ -352,6 +352,15 @@ } static VALUE +gobj_run_dispose(self) + VALUE self; +{ + g_object_run_dispose(G_OBJECT(RVAL2GOBJ(self))); + rb_gc(); + return Qnil; +} + +static VALUE gobj_inspect(self) VALUE self; { @@ -593,6 +602,7 @@ rb_define_method(cGObject, "notify", gobj_notify, 1); rb_define_method(cGObject, "thaw_notify", gobj_thaw_notify, 0); rb_define_method(cGObject, "destroyed?", gobj_is_destroyed, 0); + rb_define_method(cGObject, "run_dispose", gobj_run_dispose, 0); rb_define_method(cGObject, "initialize", gobj_initialize, -1); rb_define_method(cGObject, "ref_count", gobj_ref_count, 0); /* for debugging */ -- .:% Masao Mutoh<mu...@hi...> |
From: Masao M. <mu...@hi...> - 2003-10-05 10:17:00
|
むとうです。 On Sun, 05 Oct 2003 18:28:48 +0900 (JST) Masahiro Sakai (酒井政裕) <sa...@to...> wrote: > さかいです。 > > From: Masao Mutoh <mu...@hi...> > Subject: Re: [ruby-gnome2-devel-ja] Re: [ruby-gnome2-devel-ja] GCについての質問 > Date: Sun, 5 Oct 2003 17:49:14 +0900 > > > むとうです。 > > > > > そういえば、g_mem_set_vtable()を使って、 > > > > glibのメモリ管理そのものを置き換えてしまうという手も > > > > 使えるかも知れません。 > > > > これ、良いですね。まずはこれあてちゃってください。 > > あてときました。 どうもです。 > > > ・明示的なリソース解放手段の提供 > > > > gtk_object_destroy()の中身ってg_object_run_dispose()呼んでる > > だけなんですね。これを実装すれば良いのかな。 > > g_object_run_dispose() はサブクラス用の関数で、 > ユーザーが直接呼ぶための関数ではないです。 えーとイマイチ意味がわかりませんでした。 確かにGtk::Objectのサブクラスではg_object_run_disposeではなく gtk_object_destroy()を呼ぶべきだとは思いますが、 それより上位のクラスでGObjectのサブクラス(今回のようなケース) ではg_object_run_dispose()を呼んでも良いと思うのですが....。 そういうことではない? -- .:% Masao Mutoh<mu...@hi...> |
From: Masao M. <mu...@hi...> - 2003-10-05 13:25:13
|
むとうです。 On Sun, 05 Oct 2003 21:58:50 +0900 (JST) Masahiro Sakai (酒井政裕) <sa...@to...> wrote: > さかいです。 > > えーとイマイチ意味がわかりませんでした。 > > 確かにGtk::Objectのサブクラスではg_object_run_disposeではなく > > gtk_object_destroy()を呼ぶべきだとは思いますが、 > > それより上位のクラスでGObjectのサブクラス(今回のようなケース) > > ではg_object_run_dispose()を呼んでも良いと思うのですが....。 > > > > そういうことではない? > > g_object_run_dispose()の宣言には /*< protected >*/ がついています。 > つまり、サブクラスが内部で呼び出すためのもので、 > それ以外のところから呼び出すべきではないと思います。 protectedってそういう意味なんですか。 であれば、例えば、GLib::Object#destroyメソッドを作って (中身はrun_disposeと同じ)それを呼び出すというのでもダメですか? #同じことですけど。 要は、明示的にGLib::Objectのインスタンスを破壊できるような メソッドが無いかなぁという話なんですが。 結局のところ、なんでダメなの?という部分が全く解決できてないので 堂々巡りの質問になっちゃってますね。 どこかに参考になるモノないかなー。 #ちこっとググッたんですけどみつからなかったもんで。 #見落としかもしれませんが。 にしてもなんでダメなんだろう。 ってか通常のアプリケーションはどうやって解放しているんだろう。 GdkPixbuf使って画像をいっぱい使ってるアプリケーションの実装を 見てみればよいのかな。 -- .:% Masao Mutoh<mu...@hi...> |
From: Masahiro S. ()
<sa...@to...> - 2003-10-14 04:09:19
|
さかいです。 From: Masao Mutoh <mu...@hi...> Subject: Re: [ruby-gnome2-devel-ja] Re: [ruby-gnome2-devel-ja] GCについての質問 Date: Sun, 5 Oct 2003 22:25:09 +0900 > むとうです。 > > g_object_run_dispose()の宣言には /*< protected >*/ がついています。 > > つまり、サブクラスが内部で呼び出すためのもので、 > > それ以外のところから呼び出すべきではないと思います。 > > protectedってそういう意味なんですか。 glibやgtk+ではそういう意味で使っているように思えます。 > であれば、例えば、GLib::Object#destroyメソッドを作って > (中身はrun_disposeと同じ)それを呼び出すというのでもダメですか? > #同じことですけど。 > > 要は、明示的にGLib::Objectのインスタンスを破壊できるような > メソッドが無いかなぁという話なんですが。 実のところ、GObject一般を明示的に破壊するような 公開された関数は無いはずです。 > 結局のところ、なんでダメなの?という部分が全く解決できてないので > 堂々巡りの質問になっちゃってますね。 > どこかに参考になるモノないかなー。 > #ちこっとググッたんですけどみつからなかったもんで。 > #見落としかもしれませんが。 > > にしてもなんでダメなんだろう。 一言で言えば「想定していない」からでは? そのオブジェクトを使ってる他のコードが、 オブジェクトが明示的に破棄されることを想定していない場合、 Segmentation Fault する可能性だってありますし。 > ってか通常のアプリケーションはどうやって解放しているんだろう。 明示的に破壊せずに、単にunrefするだけです。 -- 酒井 政裕 / Masahiro Sakai |
From: Masao M. <mu...@hi...> - 2003-10-14 10:58:02
|
むとうです。 On Tue, 14 Oct 2003 13:09:38 +0900 (JST) Masahiro Sakai (酒井政裕) <sa...@to...> wrote: > さかいです。 > > From: Masao Mutoh <mu...@hi...> > Subject: Re: [ruby-gnome2-devel-ja] Re: [ruby-gnome2-devel-ja] GCについての質問 > Date: Sun, 5 Oct 2003 22:25:09 +0900 > > > むとうです。 > > > > g_object_run_dispose()の宣言には /*< protected >*/ がついています。 > > > つまり、サブクラスが内部で呼び出すためのもので、 > > > それ以外のところから呼び出すべきではないと思います。 > > > > protectedってそういう意味なんですか。 > > glibやgtk+ではそういう意味で使っているように思えます。 なるほど。以後、気をつけます。 > > であれば、例えば、GLib::Object#destroyメソッドを作って > > (中身はrun_disposeと同じ)それを呼び出すというのでもダメですか? > > #同じことですけど。 > > > > 要は、明示的にGLib::Objectのインスタンスを破壊できるような > > メソッドが無いかなぁという話なんですが。 > > 実のところ、GObject一般を明示的に破壊するような > 公開された関数は無いはずです。 > > にしてもなんでダメなんだろう。 > > 一言で言えば「想定していない」からでは? > > そのオブジェクトを使ってる他のコードが、 > オブジェクトが明示的に破棄されることを想定していない場合、 > Segmentation Fault する可能性だってありますし。 > > > ってか通常のアプリケーションはどうやって解放しているんだろう。 > > 明示的に破壊せずに、単にunrefするだけです。 要は、Gtk::Object#destroyに相当するモノがあれば良いなぁ、 というつもりだったんですが、考えてみれば要はそれがundefですね。 Rubyからunrefが明示的に呼び出せないので、その代わりになるものが あれば良いのに、と思っていたのですが、それは結局、RubyのGCが やるべきってことですよねぇ。 となると、Ruby-GNOME2的には大きなオブジェクトを作る際はある程度 明示的にGC.startを行わないといけないと。 そう考えると、もともと大きなオブジェクトを作ることが想定される Gdk::Pixbuf等では、以前、いがらしさんのメールにあった、 「ある程度メモリを使ったであろう時点で明示的にGCを起動」 ということをやった方が良さそう(明示的にGC.startを行う確率が減る) ですねぇ。 とはいえ、「ある程度のメモリ使用量」というのはちょっと難しい ような気もします。 何か良い判断基準があれば良いのですが。何かアイデアありませんか? 単純に回数っていう手もありますね。Gdk::Pixbuf.newを10回したら GC.startを1回やる、とか。 -- .:% Masao Mutoh<mu...@hi...> |
From: Masahiro S. ()
<sa...@to...> - 2003-10-05 12:58:45
|
さかいです。 From: Masao Mutoh <mu...@hi...> Subject: Re: [ruby-gnome2-devel-ja] Re: [ruby-gnome2-devel-ja] GCについての質問 Date: Sun, 5 Oct 2003 19:16:57 +0900 > むとうです。 > > g_object_run_dispose() はサブクラス用の関数で、 > > ユーザーが直接呼ぶための関数ではないです。 > > えーとイマイチ意味がわかりませんでした。 > 確かにGtk::Objectのサブクラスではg_object_run_disposeではなく > gtk_object_destroy()を呼ぶべきだとは思いますが、 > それより上位のクラスでGObjectのサブクラス(今回のようなケース) > ではg_object_run_dispose()を呼んでも良いと思うのですが....。 > > そういうことではない? g_object_run_dispose()の宣言には /*< protected >*/ がついています。 つまり、サブクラスが内部で呼び出すためのもので、 それ以外のところから呼び出すべきではないと思います。 -- 酒井 政裕 / Masahiro Sakai |
From: Masahiro S. ()
<sa...@to...> - 2003-10-05 09:28:39
|
さかいです。 From: Masao Mutoh <mu...@hi...> Subject: Re: [ruby-gnome2-devel-ja] Re: [ruby-gnome2-devel-ja] GCについての質問 Date: Sun, 5 Oct 2003 17:49:14 +0900 > むとうです。 > > > そういえば、g_mem_set_vtable()を使って、 > > > glibのメモリ管理そのものを置き換えてしまうという手も > > > 使えるかも知れません。 > > これ、良いですね。まずはこれあてちゃってください。 あてときました。 > > ・明示的なリソース解放手段の提供 > > gtk_object_destroy()の中身ってg_object_run_dispose()呼んでる > だけなんですね。これを実装すれば良いのかな。 g_object_run_dispose() はサブクラス用の関数で、 ユーザーが直接呼ぶための関数ではないです。 -- 酒井 政裕 / Masahiro Sakai |
From: Hiroshi I. <ig...@ru...> - 2003-10-05 01:14:27
|
いがらしです。 At Sun, 05 Oct 2003 03:30:53 +0900 (JST), Masahiro Sakai (酒井政裕) <sa...@to...> wrote: > > そういえば、g_mem_set_vtable()を使って、 > glibのメモリ管理そのものを置き換えてしまうという手も > 使えるかも知れません。 これができるなら、同プロセス内のglib管理下のメモリに 関しては解決できるでしょうね。ただこれ以外にも ・メモリ以外のリソース(File Descriptorなど) ・他プロセス(ex. Xサーバ)側のリソース があって、 ・オブジェクト生成時の救済 (リソースが足りなかったらrb_gc()を呼んでから再試行。 ex. rubyのio.c, socket.c) ・明示的なリソース解放手段の提供 も必要になる場面はあると思います。 もちろん、まず酒井さんのパッチは入れるべきだと思います。 -- 五十嵐 宏 (Hiroshi IGARASHI) |