参考になりそうな本でも構いません
My.Application.Info.WorkingSetとdebug.writelineをいたるところに配置することで、大体の発生箇所についてめどが立ったこともないのですが、そこから先の原因箇所へ絞り込むことができません
とりあえずdisposeが使えるものはできるだけusingで括ってみたり、画像とかファイルアクセスのところは気をつけたりしているつもりなんですが、一向にメモリ消費ペースが変わらず、さじを投げています
よろしくお願いします
メモリリークの原因調査のアプローチをいくつか書きます。
1.再現性を確認する。
特定の手順、特定の操作で再現するのであれば、
ある程度、原因個所が絞り込めていることになります。
次その部分を切り出した小さいプログラムを作って、
再現性があるか確認します。
これを繰り返すと、原因個所が狭めることが出来きます。
面倒であれば、プログラムをばっさり消してみて、
再現するか確認するもの手です。
また、プログラムを半分に分けて、
どっちで再現するかを繰り返すのも有効と思います。
2.画像やファイルのデータを静的変数に保持していないかを確認する。
クラス変数であっても、そのクラスのインスタンス自体を、
静的変数に保持していないかを確認する。
通常の変数はどこからも利用されなくなると、ガベージコレクション(GC)の
回収対象になって、そのうちGCが破棄してくれますが、静的変数は、
大量データを格納しない等、メモリ管理に気をつける必要があります。
3.ループ処理の中で、ListにデータをAddしている箇所を確認する。
Listが静的変数だったりすると、Deleteしない限りは増え続けます。
4.各種のプロファイラを使ってみる。
http://d.hatena.ne.jp/Wacky/20080823/1219500273
todo36さんありがとうございます。
CLR プロファイラはよくわからなくて挫折していたのですが、検討させていただきます。
実際にメモリリークしているのでしょうか?
.NET はガベージコレクタがあるので
ファイルやネットワーク、データベースアクセスなど
一部で dispose する以外は意図的なメモリ解放は必要ないはずです。
ただ、実際にメモリがいつ解放されるかは保障されていません。
必要でなくなった時点ですぐに開放したいということでしょうか?
SweetSmile1978さんありがとうございます。
タイマーで定期的にとある処理をするWindowsフォームプログラムを作っています。
そのとある処理が行われるたびにメモリーは多少増減するものの、全体的には増加傾向となっている(最初のころに戻ることはない)ので、メモリーリークの疑いが濃厚だと考えています。
メモリリークの原因調査のアプローチをいくつか書きます。
1.再現性を確認する。
特定の手順、特定の操作で再現するのであれば、
ある程度、原因個所が絞り込めていることになります。
次その部分を切り出した小さいプログラムを作って、
再現性があるか確認します。
これを繰り返すと、原因個所が狭めることが出来きます。
面倒であれば、プログラムをばっさり消してみて、
再現するか確認するもの手です。
また、プログラムを半分に分けて、
どっちで再現するかを繰り返すのも有効と思います。
2.画像やファイルのデータを静的変数に保持していないかを確認する。
クラス変数であっても、そのクラスのインスタンス自体を、
静的変数に保持していないかを確認する。
通常の変数はどこからも利用されなくなると、ガベージコレクション(GC)の
回収対象になって、そのうちGCが破棄してくれますが、静的変数は、
大量データを格納しない等、メモリ管理に気をつける必要があります。
3.ループ処理の中で、ListにデータをAddしている箇所を確認する。
Listが静的変数だったりすると、Deleteしない限りは増え続けます。
4.各種のプロファイラを使ってみる。
http://d.hatena.ne.jp/Wacky/20080823/1219500273
Oyama1102さんありがとうございます
1.フォーム処理などが絡んで分離が難しいので、My.Application.Info.WorkingSetとdebug.writelineをいたるところに配置する方法を取っていたのですが、検討します
2.ListViewでサムネイルを一覧表示している(そしてリストは操作やタイマー処理で書き換わる)プログラムなので、怪しいと考えています
改めて確認してみます
3.ジェネリックのList早い!もうArray.Resizeとか使えない!
と、調子に乗ってあちこちで使いまくっていたので確認してみます
4.参考にさせていただきます
4番ですが
EQATEC Profiler
http://www.eqatec.com/tools/profiler
が良さげですね、また試してみます!
ProcessExplorer でハンドルの一覧を確認して、リークしてるっぽいオブジェクトの種類や内容から、作ったやつを突き止める、ということを回答しようと思ってたのですが、こちらのほうが良さそう。
http://blog.goo.ne.jp/pianyi/e/fa93d5ea85809c85a7aaf395fc50565f
でかい塊がドカンとリークしているような場合には、一発で解決する可能性も。
小さいつぶつぶがたくさんリークしていると、結構つらいものがありますね。
.NET って真剣に使ったことは無いんですが、ガーベジコレクタはあまり頭が良く無さそうな感じ。
回答するにあたって調べたところ、こんな書き込みを見つけました。
http://i-learn-try-error-and-try.blogspot.jp/2009/09/vbnet.html
- 循環参照はうまく解決できない。
- Nothingを入れる前に入っている変数のサイズ分しか解放されないっぽい。
後者は、特に信じられないですが、本当だとすると、こんなコードを書かなきゃいけないということになってしまいます。
a = New ... ... a = Nothing ' (?_?) a = New ... ... a = Nothing
こんなの、自分だけじゃ絶対に編み出せない...
なんか、まとまってませんが、何かの参考になれば。
a-kuma3さんありがとうございます
WinDbgも挑戦してみたものの、イマイチつうまく動かせなくて挫折していたのですが、検討してみます
なお、なんでも最後はNothing作戦について、ここがメモリーを食っているだろうというところに入れてみたのですが、My.Application.Info.WorkingSetとタスクマネージャ曰くあまり改善していないようです
もう解決しました?
.netのプロファイラならhttp://memprofiler.com/が使いやすかった記憶があります。
http://memprofiler.com/findmemoryleaks.aspx
一度検討してください。
holoholobirdさんありがとうございます。
まだ個人的にいろいろあって、EQATEC Profilerをインストールしたところで終わっています。
memprofiler.comもわかりやすそうなので、また検討してみます。
Oyama1102さんありがとうございます
2013/05/31 16:22:271.フォーム処理などが絡んで分離が難しいので、My.Application.Info.WorkingSetとdebug.writelineをいたるところに配置する方法を取っていたのですが、検討します
2.ListViewでサムネイルを一覧表示している(そしてリストは操作やタイマー処理で書き換わる)プログラムなので、怪しいと考えています
改めて確認してみます
3.ジェネリックのList早い!もうArray.Resizeとか使えない!
と、調子に乗ってあちこちで使いまくっていたので確認してみます
4.参考にさせていただきます
4番ですが
2013/05/31 16:34:26EQATEC Profiler
http://www.eqatec.com/tools/profiler
が良さげですね、また試してみます!