[Ruby/Tk]TkPhotoImageでメモリリーク

Ruby/Tk の TkPhotoImage でメモリーリークしてしまった。
Ruby はガベージコレクションがあるからメモリリークとは無縁☆、とか思っていたけど、どうやらTcl/Tkが一枚噛んでいると、そうもいかないようだ。

下のように、調子に乗ってTkPhotoImage.newを作りまくると、どんどんとメモリが堆積される。

↓実行結果

普通のPNG画像を1000回読み込んだら、1.5GBまでメモリが腫れ上がってしまった。ちなみに、

の部分を

などと書き換えても無駄だ。.new が Tcl/Tk を叩き続けてメモリを確保してしまうようだ。

さて、Ruby/Tkで何か問題があった場合、Rubyでググるのは人生の無駄。Tkinterでググれ、というのは古人の知恵であるが、

こちらのTkinterの方も苦戦している。しかし、その苦戦内容がRubyとちょっと違っておもしろかった。「PhotoImageを生成しても、画像が表示されない」らしい。いわく、

PhotoImage()はPhotoImageオブジェクトを生成するけど、それを適当なグローバル変数などに入れておかないと、すぐに消滅してしまうのだろう。このtkinterの仕様が不親切な設計だと思うのは理解が足りないからだろうか。

などと書かれている。どうやらPythonでは、Rubyとは違い、おせっかいなGCがそそくさとTkPhotoImageを回収してしまうため、グローバル変数にでも入れておかないと画像が全く表示できなくなるらしい。GCがちっともTcl/Tkのメモリーを回収してくれないRubyとは正反対の悩みだ。さすがグローバルのPython。なんと贅沢な悩みであろうか。

解決。
どうやらdeleteを呼べばよいようだ。

実行結果

これでメモリーの無限増殖はなくなった。
少しはメモリを消費するようだが、常識的な範囲にとどまっている。

でも、Rubyでもメモリに気を使わなければならないことが判明して、ちょっと悲しい。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です