永井@知能.九工大です.
Ruby/Tk において,大量のキャンバスオブジェクトを生成すると,
それらのオブジェクトを消去した後もメモリが解放されないということで
相談を受けました.
一つには TkcItem#delete において,管理用のハッシュからの情報削除の際,
nil を代入するようにしていたという bug が原因でした.
# これは Hash#delete を使わないといけないですよね.
# 手が空いている方がありましたら,修正して commit していただけると
# 助かります.
ですが,これを修正しても,Ruby は多量のメモリを占有したままです.
ご存知の方はご存じの通りの体調ですので,
きちんとした問題追跡やデバッグは行っていないのですが,
結局のところ,ウィジェットパスとオブジェクトとの対応を
管理するハッシュが一時的に肥大化して大量のメモリを要求し,
それが不要 ( 管理ハッシュがほぼ空 ) になっても
Ruby がそのメモリを確保したままになっているということのようです.
例えば irb などで
-------------------------------------
h = {}
(1..1000000).each{|i| h[i] = i}
(1..1000000).each{|i| h.delete(i)}
h = nil
GC.start
-------------------------------------
などとやっても 24MB ほどのメモリを確保したままとなります.
で,本題なのですが,「当面はこれ以上のメモリは必要としないよ」
という状況で,余っているメモリを解放する手段を提供するというのは
難しいでしょうか.
もちろん自動でというのは効率上も無理でしょうから,
スクリプトからの手動の要求によってという話です.
「一時的なりともそれだけを必要とするんだから仕方がない」というのも
事実だとは思いますが,長期間稼働するアプリケーションで
一時的に作業に多量のメモリを必要とするというケースを考えると
メモリ解放手段が用意されていると嬉しいと思うのですが.
--
永井 秀利 (九工大 知能情報)
nagai / ai.kyutech.ac.jp