- PR -

MDIフォームのメモリ開放について

投稿者投稿内容
茶坊主
会議室デビュー日: 2005/10/05
投稿数: 7
投稿日時: 2005-10-05 17:16
初めて投稿します。宜しくお願いします。

VB.NETのMDIフォームについて教えて下さい。
現在、親フォームから子フォームを起動し、終了した際に使用メモリが減らない
という現象が出ています。
サンプルで簡単なフォームを作成しましたがやはり同じ結果になりました。
現象例.
タスクマネージャのプロセスタグで使用しているメモリ使用量をチェックする。
親フォーム起動時、約19M
子フォーム起動中、約21M
子フォーム終了後、約21M(子フォームは他に何も起動していない状態)

以下、サンプルのコードです。
◆親フォーム◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim FRM As Object
Try
' 必要な変数を宣言する
Dim hMdiChildren As Form()

' 保有してるすべての MDI 子フォームを取得する
hMdiChildren = Me.MdiChildren

' すべての MDI 子フォームを閉じる
For Each hMdiChild As Form In hMdiChildren
hMdiChild.Close()
hMdiChild.Dispose()
hMdiChild = Nothing
GC.Collect()
Next hMdiChild
hMdiChildren = Nothing

FRM = New Form2
'親フォームをこのフォームにする
FRM.MdiParent = Me
'子フォームを表示する
FRM.SHOW()
FRM.Location.Offset(FRM.Location.X * -1, 0)
Catch Err As Exception
Finally
FRM = Nothing
GC.Collect()
End Try
End Sub

◆子フォーム◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆
Private Sub Form2_Closed(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Closed
Me.Dispose(True)
System.GC.Collect()
End Sub


ご教授のほうよろしくお願いします。

[ メッセージ編集済み 編集者: 茶坊主 編集日時 2005-10-05 17:56 ]
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-10-05 17:32
何か、私のサイトに似たようなソースがあったような。(変数のクセもそのままに)
まあそれはおいといて。

引用:

茶坊主さんの書き込み (2005-10-05 17:16) より:

Dim FRM As Object


何故に Object?

引用:

hMdiChild = Nothing
FRM = Nothing


意味はないです。

引用:

hMdiChildren = Nothing


こちらは配列なので意味はあります。
ただし、GC を多少手助けする程度のもので必須ではありせん。

引用:

コード:

    Private Sub Form2_Closed(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Closed
        Me.Dispose(True)
        System.GC.Collect()
    End Sub




これ、おかしいと思いませんか?

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
なおこ(・∀・)
大ベテラン
会議室デビュー日: 2004/04/08
投稿数: 174
お住まい・勤務地: 東京都
投稿日時: 2005-10-05 17:34
お世話になります。

http://www.atmarkit.co.jp/fdotnet/dotnettips/021gc/gc.html
によると
引用:

 .NET Frameworkのガベージ・コレクタは、ジェネレーション(世代)という概念を持っており、ガベージ・コレクションを効率よく実行できる。ジェネレーションとは、生成されてから間もないオブジェクトと、時間が経過したオブジェクトを分ける概念である。一般的に、作成されてから時間が経過したオブジェクトは解放される可能性が低く、生成されてから間もないオブジェクトは解放される可能性が高いことから、後者のオブジェクトだけを調べて解放処理を行うことで効率アップするというものだ(作成から長時間が経過しても解放されないオブジェクトは、今後も長期にわたり使用され続ける可能性が高い)。


とあるので、これが原因では?
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-10-05 17:42
こんにちは、じゃんぬ です。

引用:

なおこ(・∀・)さんの書き込み (2005-10-05 17:34) より:

とあるので、これが原因では?


GC.Collect メソッドで明示化しても?

あ、本題を忘れていました。

引用:

茶坊主さんの書き込み (2005-10-05 17:16) より:

親フォーム起動時、約19M
子フォーム起動中、約21M
子フォーム終了後、約21M(子フォームは他に何も起動していない状態)


もっとフォーム数を増やしてやって頂けませんか?
この程度だと、異常だと断定できません。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
茶坊主
会議室デビュー日: 2005/10/05
投稿数: 7
投稿日時: 2005-10-05 17:44
じゃんぬねっと様、なおこ(・∀・)様、返信ありがとうございます。

引用:
--------------------------------------------------------------------------------
何故に Object?
--------------------------------------------------------------------------------
実際のPG側では複数のFormを1つのオブジェクトに入れて
パターン別に起動していたためサンプルも同じように書きました。

引用:
--------------------------------------------------------------------------------
コード:
--------------------------------------------------------------------------------
Private Sub Form2_Closed(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Closed
Me.Dispose(True)
System.GC.Collect()
End Sub
--------------------------------------------------------------------------------
これ、おかしいと思いませんか?
--------------------------------------------------------------------------------
初心者なものでとりあえず書かないとダメだという認識しか有りません。
何がおかしいのか教えて頂けませんか。
茶坊主
会議室デビュー日: 2005/10/05
投稿数: 7
投稿日時: 2005-10-05 17:52
お世話になります。
テスト的に子フォームをコピーしてフォームを増やしてチェックしました。
基本的に起動する・落とすの動作を繰り返します。(複数画面同時起動は行いません)
新しいフォームが起動する度に約2M程度増えていきます。
既に一度でも起動されたフォームを起動するとメモリに変化はありませんでした。
囚人
ぬし
会議室デビュー日: 2005/08/13
投稿数: 1019
投稿日時: 2005-10-05 17:55
こんにちは。

全世代のガベージコレクションを実行したとしても、管理ヒープに解放しているだけで、必ずしも OS に返しているとは限らないのでは?
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2005-10-05 21:53
むか〜〜〜し、
「ギガ近くまで確保してるけど、本当に大丈夫かよ?!」
って、ここに書いた記憶があります(^◇^

「そんなもんです」
って、返答されたように、覚えています。。。


引用:

実際のPG側では複数のFormを1つのオブジェクトに入れて
パターン別に起動していたためサンプルも同じように書きました。


だったら Form で受ければいいのでは?

引用:

初心者なものでとりあえず書かないとダメだという認識しか有りません。
何がおかしいのか教えて頂けませんか。


 IDisposable インターフェイスを実装するクラスのインスタンスを、使い終わったら Dispose メソッドをコールします。
 Form.Close メソッドは、Dispose メソッドの別名として機能します(ちと、注意が必要)。ですから、Closed イベントで、わざわざ Dispose する必要も、GC.Collect する必要もありません。詳細は、MSDN を読んでください。
 わからなかった場合は、どのあたりがわからなかったか、教えてください。FeedBack のネタにしますので。
_____________________________________________________________________________
□ Posted by Jitta on 2005/10/05
じったのノート
□ Microsoft MVP :Visual Developer ASP/ASP.NET Oct.2005-Sept.2006
_________________

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