MVVMアプリケーションにおけるメモリリーク対策
フレームワークレベルでは丁寧なメモリリーク対策が必要と思いますが、アプリケーションレベルではメモリリークに対して神経質なコードを書かなくても良いと思っています。
ライフサイクルの長いオブジェクトを識別し管理する
メモリリークの定義もいろいろありますが、少しぐらいViewやViewModelのインスタンスが残る程度は問題にせず、継続的にメモリが増加するような場合について対策できていれば多くのアプリでは問題にならないのではないでしょうか?
ようは、MVVMのViewやViewModel、Modelのライフサイクルがそれほど長くないのであればお互いが参照していても問題が発生しないという考え方で、あとは、ライフサイクルの長いオブジェクトを識別して適切に管理するという、一般的なメモリリーク対策に落とし込むアイデアです。
MVVMの長いライフサイクルをもつオブジェクトとしては、Viewであれば起動時のメニューウインドウ(非表示にしているがインスタンスが常に存在することもある)、ViewModelやModelはキャッシュとして利用しているStatic変数に代入したオブジェクトなどが思い浮かびます。これらをしっかり識別して管理するということです。
リークしていないか確認する仕組みを入れる
あとは、丁寧なコードを組んでいたとしても予期せぬこと(深刻なメモリリークに悩まされるWPF)があるかもしれませんので、予備対策としてViewModelとViewをWeakReferenceを使ってリークしていないかチェックする仕組みを組み込めばかなり安心できるのではないでしょうか?
//メモリ上に存在するかチェックするためにWeakReferenceをListに登録する private List<WeakReference> viewList = new List<WeakReference>(); private List<WeakReference> viewModelList = new List<WeakReference>(); viewList.Add(new WeakReference(view)); viewModelList.Add(new WeakReference(vm)); //メモリ上に存在するView、ViewModelのチェック GC.Collect(); GC.WaitForPendingFinalizers(); Debug.WriteLine("Active View:" + viewList.Count(x => x.IsAlive).ToString()); Debug.WriteLine("Active ViewModel:" + viewModelList.Count(x => x.IsAlive).ToString());