C#ではメモリリークはほとんど心配ないと思っていたが,WPFアプリケーションを作っていると,メモリリークが頻繁に起きることが分かって恐ろしくなった.
まず,参考のページ「俺が遭遇したWPFイメージコントロールのメモリーリークと回避法(?)の1つ」を参考にすると,Imageコントロールはよくリークを起こす.参考のページのサンプルコードの最後の方にあるように,明示的にSourceにnullを入れてやらないと割と残るようだ.
リーク以外に,キャッシュという仕組みもありわかりにくい.xamlにイメージのファイル名を直接書いていると一度使ったイメージはキャッシュされ次の使用が速くなる(らしい).
このほか,UserControlもうまく設計していない場合,リークを起こす.Imageを使う場合やTimerを使う場合にはIDisposalインタフェースを実装して明示的にDisposeを呼び出すことを強く推奨する.TimerなんかはいったんStartしたままコントロールを破棄してしまうと(Windowを閉じるなど),一見コントロールが使えなくなくなっても残ってしまう.しかも,消えるタイミングが不定で恐ろしいバグになる(たいていはtickも残る).
Visual Studio 2017 ProfessionalやCommunityなら診断ツールを用いてヒープを表示させると,参照しているオブジェクト種類の一覧と参照されているオブジェクトの一覧が取れるのでデバッグの助けになる.
ポイントはImageが残っていないか?Start()を呼んだままのTimerが残っていないか?かな
タグ:WPF