locked
メモリリークが発生するコードの記述方法について RRS feed

  • 質問

  • こんにちは。アべです。

    Silverlight4にて開発をおこなっております。

    UIの負荷試験をするとメモリリークするのですが
    そもそも.NET Frameworkでどのようなコードを
    記述するとメモリリークを引き起こすのでしょうか?

    どこからも参照されていないインスタンスは
    解放されるし

    AインスタンスとBインスタンスがお互いが
    参照しあっていても、エントリポイントの
    インスタンスから両方を切り離すと解放されます。

    エントリポイントのインスタンスから
    切り離してもメモリリーク(GCで解放されない)するコードって
    どのように記述するのでしょうか?

    コーディングイメージがわかれば
    対処しようがあるのですが
    そのイメージがついておらず相談させて頂きました。



    2011年5月26日 11:05

回答

  • おそらくなんですが、イベントハンドラーの削除し忘れではないでしょうか。

    Silverlightでは、画面に表示されなくなったUI要素(たとえば、ListBoxでスクロールによって隠れた要素)のインスタンスを破棄、再表示時に再生成したりします。

    このとき、その要素がモデル(あるいはViewModel)のイベント(INotifyPropertyChangedのPropertyChangedイベントなど)を購読(+=)していると、モデル側がUI要素のインスタンスを握り続けて、メモリリークします。

    対策としては、自前でイベントハンドラーの登録/解除(+=/-=)するのを辞めて、全てデータバインディングの仕組みに頼る(要するに、MVVMパターンを取る)ことになると思います。


    IWANAGA Nobuyuki
    • 回答の候補に設定 山本春海 2011年6月3日 9:05
    • 回答としてマーク 山本春海 2011年6月10日 5:44
    2011年5月26日 12:29
  • 以下辺りも参考になると思います。

    MVVMでメモリリークしちゃってました 原因と対策編
    http://d.hatena.ne.jp/okazuki/20110227/1298817065

    イベントリスナが先にお亡くなりになっています。あれ?残念ながらメモリリークです。あのね、WeakEventパターンを使うといいと思うんだ。WeakEventManagerから派生して、抽象的なWeakEventTriggeredManager<TSource, TEventArgs>クラスを作ってみよう。
    http://d.hatena.ne.jp/zecl/20090509/p1

     


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
    • 回答の候補に設定 山本春海 2011年6月3日 9:06
    • 回答としてマーク 山本春海 2011年6月10日 5:44
    2011年5月27日 3:18
    モデレータ

すべての返信

  • おそらくなんですが、イベントハンドラーの削除し忘れではないでしょうか。

    Silverlightでは、画面に表示されなくなったUI要素(たとえば、ListBoxでスクロールによって隠れた要素)のインスタンスを破棄、再表示時に再生成したりします。

    このとき、その要素がモデル(あるいはViewModel)のイベント(INotifyPropertyChangedのPropertyChangedイベントなど)を購読(+=)していると、モデル側がUI要素のインスタンスを握り続けて、メモリリークします。

    対策としては、自前でイベントハンドラーの登録/解除(+=/-=)するのを辞めて、全てデータバインディングの仕組みに頼る(要するに、MVVMパターンを取る)ことになると思います。


    IWANAGA Nobuyuki
    • 回答の候補に設定 山本春海 2011年6月3日 9:05
    • 回答としてマーク 山本春海 2011年6月10日 5:44
    2011年5月26日 12:29
  • 有難うございます。

    Siverlightでのイベントハンドラ―の使用は気を付けます。
    (テストコードで本当にリークするかチェックしてみます。)

    MVVMで作るのは素晴らしいと思います。
    ただ、私のリテラシのせいか、意外に簡単なこともできないので、MVVMだけでは厳しい部分もあります。

    まずは、リークのコードを確認してから、MVVMへの換装を進めます。

    有難うございました。

     

     

    2011年5月27日 3:01
  • 以下辺りも参考になると思います。

    MVVMでメモリリークしちゃってました 原因と対策編
    http://d.hatena.ne.jp/okazuki/20110227/1298817065

    イベントリスナが先にお亡くなりになっています。あれ?残念ながらメモリリークです。あのね、WeakEventパターンを使うといいと思うんだ。WeakEventManagerから派生して、抽象的なWeakEventTriggeredManager<TSource, TEventArgs>クラスを作ってみよう。
    http://d.hatena.ne.jp/zecl/20090509/p1

     


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
    • 回答の候補に設定 山本春海 2011年6月3日 9:06
    • 回答としてマーク 山本春海 2011年6月10日 5:44
    2011年5月27日 3:18
    モデレータ
  • こんにちは、kiyo7447R2 さん。

    MSDN フォーラムのご利用ありがとうございます。オペレーターの山本です。

    参考になる情報をいただいていると思われましたので、他の方にもこの情報を有効活用していただくよう、勝手ながら回答としてマークさせていただきました。
    iwanaga さん、trapemiya さん、情報ありがとうございます。

    もし他にも情報をお持ちの方がいらっしゃいましたら、是非投稿をお願いいたします。

    今後とも MSDN フォーラムをよろしくお願いいたします。それでは。
                                                              
    日本マイクロソフト株式会社 フォーラム オペレーター 山本 春海

    2011年6月10日 5:44