- PR -

MDI子フォームの使用メモリが開放されない

1
投稿者投稿内容
いわん
会議室デビュー日: 2004/03/09
投稿数: 3
投稿日時: 2004-03-09 21:07
初投稿です。よろしくお願いします。

VB.NETでMDIアプリケーションを作成しているのですが、特定の操作で
子フォームを閉じるとガベージコレクションを行ってもメモリが開放されない
現象が発生し、対処方法をさがしています。

状況を詳しく説明しますと、子フォーム作成後普通に子フォームのクローズボタン
[×]で閉じると問題なくメモリが開放されているのですが、LayoutMdiメソッドで
並べ変えを行ったり、親フォームのメソッドから子フォームの Close メソッドを
呼んで子フォームを閉じた場合は、ガベージコレクションを行ってもメモリが開放
されません。
ガベージコレクションを行っている場所は親フォームの MdiChildActivate イベント
ハンドラです。メモリの使用量はタスクマネージャで確認しました。

常時稼動システムのプログラムのため、使用メモリが増加する一方というのは
問題があります。どなたか対処方法がわかりましたらよろしくお願いします。
いわん
会議室デビュー日: 2004/03/09
投稿数: 3
投稿日時: 2004-03-14 06:49
原因が判明しました。

子フォームに貼り付けた PictureBox を明示的に削除していなかったのが
原因だったようです。 Dispose メソッドで BictureBox1 = Nothing と
することでメモリが開放されるようになりました。
その他、子フォームに貼り付けたコントロール全て適切な後始末を行わないと
メモリが開放されずに残ってしまうようです。

まだ、条件によっては開放される場合もあるという疑問は残りますが
とりあえず問題は解決しました。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-03-15 18:36
引用:

いわんさんの書き込み (2004-03-14 06:49) より:

その他、子フォームに貼り付けたコントロール全て適切な後始末を行わないと
メモリが開放されずに残ってしまうようです。

まだ、条件によっては開放される場合もあるという疑問は残りますが
とりあえず問題は解決しました。


 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/09
投稿数: 3
投稿日時: 2004-03-15 21:41
Disposeメソッドではメモリは開放されませんでした。
私もそれで引っかかってなかなか問題を解決できなかったのですが。
それから、貼り付けたPicturBoxコントロールはまだしも、Formの
BackgroundImageプロパティに画像を貼り付けた場合でさえ
自分でBackgrountImageのDisposeを呼ばないとメモリが開放され
ませんでした。
どうもよくわかりません。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-03-16 06:34
引用:

いわんさんの書き込み (2004-03-15 21:41) より:

Disposeメソッドではメモリは開放されませんでした。


 ごめんなさい、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

スキルアップ/キャリアアップ(JOB@IT)