- - PR -
MDI子フォームの使用メモリが開放されない
1
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2004-03-09 21:07
初投稿です。よろしくお願いします。
VB.NETでMDIアプリケーションを作成しているのですが、特定の操作で 子フォームを閉じるとガベージコレクションを行ってもメモリが開放されない 現象が発生し、対処方法をさがしています。 状況を詳しく説明しますと、子フォーム作成後普通に子フォームのクローズボタン [×]で閉じると問題なくメモリが開放されているのですが、LayoutMdiメソッドで 並べ変えを行ったり、親フォームのメソッドから子フォームの Close メソッドを 呼んで子フォームを閉じた場合は、ガベージコレクションを行ってもメモリが開放 されません。 ガベージコレクションを行っている場所は親フォームの MdiChildActivate イベント ハンドラです。メモリの使用量はタスクマネージャで確認しました。 常時稼動システムのプログラムのため、使用メモリが増加する一方というのは 問題があります。どなたか対処方法がわかりましたらよろしくお願いします。 | ||||
|
投稿日時: 2004-03-14 06:49
原因が判明しました。
子フォームに貼り付けた PictureBox を明示的に削除していなかったのが 原因だったようです。 Dispose メソッドで BictureBox1 = Nothing と することでメモリが開放されるようになりました。 その他、子フォームに貼り付けたコントロール全て適切な後始末を行わないと メモリが開放されずに残ってしまうようです。 まだ、条件によっては開放される場合もあるという疑問は残りますが とりあえず問題は解決しました。 | ||||
|
投稿日時: 2004-03-15 18:36
Nothingを代入するのではなく、Disposeメソッドをコールします。Formの場合、FormのDisposeメソッドをコールすれば、保持しているコントロールのDisposeが呼ばれるように、自動でコーディングされていませんか? ・・・あった。protectedにオーバーライドされているDisposeを、trueを引数にしてコールすれば、保持しているコンポーネントのDisposeがされます。Protectedなので、Closedイベントあたりでコールしてやればよいかと。 その他、確実に解放するためには、IDisposableインタフェースにキャスト可能か調べ、キャスト可能ならばキャストしてDisposeをコールします。これをtry〜catch〜finallyの、finallyブロックに入れれば、さらに良い。。。が、面倒くさい!!Cの#defineみたいなことができればいいのに。。。(そのためのusingだって?) 変数宣言 try catch finally if typeof 変数 is idisposable then ctype(変数, idisposable).dispose end if end try ### しかし、FormのCloseメソッドは、Disposeと等価なのでは?という疑問は残る。。。 ↑MSのガイドラインに拠る http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/cpgenref/html/cpconfinalizedispose.asp | ||||
|
投稿日時: 2004-03-15 21:41
Disposeメソッドではメモリは開放されませんでした。
私もそれで引っかかってなかなか問題を解決できなかったのですが。 それから、貼り付けたPicturBoxコントロールはまだしも、Formの BackgroundImageプロパティに画像を貼り付けた場合でさえ 自分でBackgrountImageのDisposeを呼ばないとメモリが開放され ませんでした。 どうもよくわかりません。 | ||||
|
投稿日時: 2004-03-16 06:34
ごめんなさい、Disposeでは解放せず、『解放して良いとマークする』としましょうか。それとも『開放』?C言語で言うところのfreeではありません。とりあえず、この投稿中は「開放」を使います。 まず、Disposeで「開放」できるのは『アンマネージドメモリ』です。Dispose後の『アンマネージドメモリ』や『マネージドメモリ』は、ガベージコレクタが「解放」します。もっとも、Disposeメソッド内で「解放」させることも可能です(内部の作りの話)。 いわんさんがおっしゃる『解放できなかった』は、「使用メモリが下がらなかった」ということだと思いますが、ガベージコレクタはいつ動くかわからないので、「Disposeしたから即解放」ではありません。Disposeは開放するだけで、アプリケーションがメモリを解放するのはガベージコレクタが動作したときです。 また、COMリソースを解放(こっちは解放)するには、別のメソッドが必要だったりします。 http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=2904&forum=7 http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=2683&forum=7 この辺、参考になるでしょうか? 下の方のスレッドで、NothingButXMLInfoSetさんが提示されているツール、使ってみてください。 |
1