[開発] インスタンスメソッドの参照を保存するだけでメモリリーク

新しい Progression 開発に向けて、少しづつ技術検証をしているのですが、ちょっとどうしようもない状況に遭遇したのでメモ。

まずは以下の wonderfl を実行してみてください。
※同時に実行すると正しい結果にならないので、ブラウザを再起動するなどして個別に実行してください。

正常な動作
http://wonderfl.kayac.com/code/951c262d616b807aa22f7373c78178e2daa35906

問題版(メモリが完全に解放されない)
http://wonderfl.kayac.com/code/b954ee245607250e4e047ea8cf53a5fbb13e0f49#code_forked

今回は 100000 個の MyObject インスタンスでの検証ですが、だいたい 2.4 MB 程の差が生じてしまっています。
この問題の影響範囲まではまだ確認できていませんが、割とシンプルな操作で解放不能になってしまうので、何かしらの参照が残ってしまっている場合には、解放できないオブジェクトが増えていってしまいそうですね・・・。

この件について何か情報をお持ちの方がいれば、本エントリーのコメント、またはフォーラムまでお寄せください。

追記
クラスメソッドじゃなくてインスタンスメソッドでした。

コメント / トラックバック4件

  1. arkw より:

    既知かと思いますが、Dictionaryで、弱参照を利用してメソッドを保持するのは、どうでしょうか?
    若干メモリを食いますが、、、

  2. admin より:

    > arkw さん
    情報ありがとうございます。
    Dictionary に保持する場合、それ自体のメモリ消費は仕方ないとしても、参照を取得する毎に for … in しないと行けない部分がオーバーヘッドとして気になりますね・・・。

    function getItem(): {
    for ( var item:* in dic ) { return item; }
    return null;
    }

    function hoge(): {
    }

    var dic:Dictionary = new Dictionary( true );
    dic[hoge] = true;
    trace( getItem() );

    この辺りについてももうちょっと検証して報告しますね。

  3. dseg より:

    そもそもの趣旨と全然離れるかもしれませんが、
    こういうのはどうですかね?

    class MyObject {
    public function MyObject() {
    // クラスメソッドをローカル変数に代入して破棄する
    MyObject.prototype.myMethod = function():void {};
    var value:Function = MyObject.prototype.myMethod;
    value = null;
    }

    // public function myMethod():void {
    // }
    }

  4. admin より:

    > dseg さん
    情報ありがとうございます。
    匿名関数の場合には、問題なくメモリ解放できそうですね。
    ただ、今回の場合にはインスタンスに定義済みのメソッドの参照を格納したいと思っているので、ちょっと趣旨とは違ってしまいますね。

コメントをどうぞ