QA@IT

VB2010であるフォームを表示する際に膨大なメモリを必要とする(メモリリーク?)

3699 PV

お世話さまです。

VS2010のVB.NETで開発中のアプリでの現象なのですが、FormAからFromBをshowすると
FromBがロードされて表示されるまでに1分近い時間がかかり、その間をパフォーマンスモニタで
見てみるとメモリが500MBぐらいまでどんどん上昇していって、ようやくFromBが表示されます。
(表示後にメモリは解放されています。)

不思議なのは、このアプリのソリューションからデバック開始で実行するとそのようなメモリの
消費は発生せず、ビルドしたexeを実行した場合にのみ発生します。(DebugもReleaseも同様)

exeを削除してからビルドし直したり、何度かクリーンビルドをかけてもみましたが解消しませんでした。

ちなみに、
FormBには11個のタブがあり、コントロール数も結構な数にはなっているのですが、開発環境
からの実行では数秒で表示されますので納得が行きません。

このメモリの消費の根本原因を突き止める手立てはありますでしょうか?
ご教示頂けるとありがたいです。

  • PCを起動したままで 2回目のexe起動でも発生しますか?初めて起動したときだけですか?
    他の .NETアプリケーション起動後の起動でも同じですか?
    -
  • メモリの上昇について、 対象のexeプロセスのメモリの使用量が500MBぐらい増える感じですか?システムのメモリの使用量が500MBぐらい増える感じですか? -
  • あとは実行環境(OSとそのバージョン、ターゲットフレームワーク、OS,exeともにx64かx86かなど)も明記してください。 -
  • flied_onionさん、早速のレスありがとうございます。
    2回目以降も発生します。
    他の.NETアプリケーションで発生したことはありません。
    対象のexeのプロセスが上がって行きます。
    500MBと書きましたが、先ほどタブを1つづく削除して計測した時には
    11タブで1GB近くまで消費しました。
    これを2タブまで減らしたところ70MBぐらいまでになってフォームも
    サクッと表示さ
    -

回答

長いので回答に書きます。

コメントに対する回答を読みましたが(環境についてはまだ書き途中かもしれませんが)
.NET Frameworkのローディングというわけではなさそうですね。

他の.NETアプリケーションで発生したことがないのであれば、
どこかでリソースやファイルがロードされるとか自動的にデータがバインドされているのではないかというのが第一印象です。

たとえばデータ表示するにあたって最終的に出力されるのが5件でも、データ取得がreaderや絞り込みの無いSQLでの DataAdapter.Fillだった場合に一旦テーブルを丸ごととってくることになるので一時的にメモリ量が増大します。型付データセットを使っている場合なんかもそうですね。
たとえばコンボボックスのアイテムをそういった形で作成していた場合、タブの数だけテーブル全取得回数が増えるので、タブを減らすとメモリ使用量が減るわけですね。
動きとしてはそういった動きになっていないかが気になるところですが、そのあたりはソースやプロジェクトみないと何とも言えないです。

なお Visual Studioから起動した場合は起きないとのことですが、VSホストを介さず実行した場合はどうでしょうか?
以下の
■.vshost.exeファイルが生成されないようにする方法
を参考にしてみてください。

http://www.atmarkit.co.jp/fdotnet/dotnettips/831stoppdbfile/stoppdbfile.html

編集 履歴 (0)

続報です。
11あるタブの中の不要なPanel等のコントロールを整理したところ
当該フォームの表示にメモリにして1GB、時間にして1分以上かかっていたのが
600MB、33秒まで短縮できました。
ところが、当exeを他の複数のマシン(スペック的には私の開発マシンより劣る)上で
実行したところ、メモリの増加もなく2秒程度で表示されました。
つまり、完全にマシン依存の現象だったということになります。
とりあえず、エンドユーザーマシン環境では発生しない事象であることが確認とれましたので
この件は不問にすることにしました。
色々とお手数をおかけしました。
ありがとうございました。

編集 履歴 (0)

flied_onionさん、レスありがとうございます。

SQLとの連携という点では、各タブの中のListBoxにDBから読込んだ
リストをセットしているのですが、これはテーブルのレコード自体50件弱で
このデータ全てを一旦グローバル変数に格納した後、セットしています。

vshost.exeなしでビルドして実行してみましたが、相変わらずメモリも
1GBぐらいまで消費してフォームの表示される時間も同様にかかりました。

以上、宜しくお願い致します。

編集 履歴 (0)
  • 可能であれば、DBのすべてのユーザーテーブルを空か1件にして実行してみて起動時間を比較されてみては。自分がアクセスしてると思っているテーブルじゃなくて全部です(原因がわかってないので疑わしきは全て疑った方がいいです)。

    vshostの方は、vshostなしにすればVSからデバッグ実行でも遅くなりますよね?という意味です。
    -
  • タブを丸ごと削除ではなくタブのなかのコントロールを消していったり。DB接続が遅くなっていないか見てみたりするのも良いと思います。
    現在の情報だとこれぐらいしか言えませんが、新規プロジェクトでコントロールのないタブを11枚貼り付けて再現しないのであれば、なにかしら重い処理が紛れ込んでるんだと思います。
    -
  • レス、ありがとうございます。
    実は上にラベルが貼ってあるだけのパネルが存在したりと無駄もコントロールも確かにあるのでまずはそこらへんを整理してみたいと思います。
    ちなみに、vshostなしのVSからデバッグ実行では遅くなりませんでした。
    -

追記です。

11あるタブを1つづつ削除してビルドしてメモリの消費量を計測してみたのですが、やはり
タブを減らすにつれ、メモリの消費量は減って行きました。

感覚的には1つのタブにつき100MBづつ消費してるようです。

各タブには下記のようなコントロールが配置してあります。

Panel 19個
ListBox 1個
CheckBox 10個
Label 11個
ComboBox 4個
RadioButton 3個

100MBも消費するボリュームだとは思えないのですが…

編集 履歴 (0)
ウォッチ

この質問への回答やコメントをメールでお知らせします。