- PR -

【C#】 GCが子Formのインスタンスをメモリから解放するタイミング

1
投稿者投稿内容
Pony
会議室デビュー日: 2007/03/30
投稿数: 3
投稿日時: 2007-04-02 17:04
まじめまして、C#勉強中のPonyと申します。
宜しくお願いします。

GCが子Formのインスタンスをメモリから解放する
タイミングがわからずに困っております。

子FormのClassのコンストラクタ・ディストラクタに
ログをいれてインスタンス生成数を管理したいですが、
実際にログを入れてみますと以下のような動作に見えます。

 MDI形式のFormの場合、子Formを表示した際に
 子Formのクラスにコンストラクタ起動はなされますが、
 子Formを閉じた際に、ディストラクタは実行されない。

そのため、同じ子Formを何度も[表示->終了]させた場合、
子Formのインスタンスがいっぱいできてしまうように見えます。

できれば、子Form終了時にメモリ上から解放したいのですが。
可能なのでしょうか。

どなたか、ご教授のほどよろしくお願い致します。
Hongliang
ぬし
会議室デビュー日: 2004/12/25
投稿数: 576
投稿日時: 2007-04-02 17:31
そもそも、Close とメモリの解放は無関係です。Close(より一般的には Dispose) の対象はアンマネージドリソースであり、つまりメモリ「以外」の解放です。
デストラクタというのは C# では構文の名前でしかなく、実際にはファイナライザとして GC によってインスタンスが削除されるときに実行されますが、アンマネージドリソースさえ使っていないのならわざわざファイナライザを動かす必要も無いので、Close(Dispose) によってアンマネージドリソースが解放されているのが保証されていればファイナライザの呼び出しを抑制するのが一般的な実装です。
えーとこの辺は MSDN を始め Web を色々漁ってください。山ほど記事があります。
GC の基本についてはこちらの記事が基本かな。
ガベージコレクション入門: Microsoft .NET Framework の自動メモリ管理 Part I
ガベージコレクション入門: Microsoft .NET Framework の自動メモリ管理 Part II

.NET ではメモリ管理を GC に管理させているため、基本的に .NET を利用する者はメモリのことを考える必要はありません。こちらが小手先にメモリを管理するよりも大抵はより賢く確保と解放を行ってくれるでしょう。
我々が管理するべきなのはメモリではなくインスタンス(の参照)です。
よねKEN
ぬし
会議室デビュー日: 2003/08/23
投稿数: 472
投稿日時: 2007-04-02 17:42
引用:

Ponyさんの書き込み (2007-04-02 17:04) より:
 MDI形式のFormの場合、子Formを表示した際に
 子Formのクラスにコンストラクタ起動はなされますが、
 子Formを閉じた際に、ディストラクタは実行されない。



・子Formを表示する
・子Formを閉じる
ということとインスタンスが生成される/破棄される
ということとは直接は関係がありません。

インスタンスが生成されるのはnewしたタイミング(表面上はなんらかのメソッドを
呼び出すことでインスタンスを生成(というか取得)するようなパターンはありますが、
それらもその"なんらかのメソッド"の中でnewしています。)

インスタンスが破棄されるのは、インスタンスを参照している変数等が1つもない状態で、
GCが起動したときです。




引用:

そのため、同じ子Formを何度も[表示->終了]させた場合、
子Formのインスタンスがいっぱいできてしまうように見えます。



それで正常です。

引用:

できれば、子Form終了時にメモリ上から解放したいのですが。
可能なのでしょうか。



明示的な解放手段はありません。
GCにまかせましょう。
#GC.Collectメソッドで明示的にGCを起動させることはできるけれど、
#乱用するようなものではありません。
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2007-04-02 17:44
引用:

できれば、子Form終了時にメモリ上から解放したいのですが。
可能なのでしょうか。



という発想が既にGCを誤解しています。

クラスインスタンスを構成する純粋な「(管理された)メモリ」の管理について、原則として、プログラマが全く考えなくてよいための仕組みがGCです。

「(管理された)メモリ」は、原則としてうっちゃらかしで構いません。

既にコメントが付いていますが、Form を閉じた時点で「解放されるべきモノ」は「メモリ」ではなく、OSが「画面上に表示されるウィンドウというもの」の管理に使用している「ウィンドウハンドル」や、それに関連する「GCとは無関係なモロモロのブツ」です。

こういった、「GCとは無関係なブツ」の解放は、Close() や Dispose() で行われます。
Pony
会議室デビュー日: 2007/03/30
投稿数: 3
投稿日時: 2007-04-02 18:40
早速丁寧なご返信を頂き、ありがとうございます。

たしかにGCの概念、及びFormの操作を誤解しておりました。
#Formを閉じた時点でメモリ自体解放されると思い込んでおりました。
失礼いたしました。

もう少しメモリ管理を勉強してみます。
1

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