- - PR -
【C#】 GCが子Formのインスタンスをメモリから解放するタイミング
1
投稿者 | 投稿内容 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2007-04-02 17:04
まじめまして、C#勉強中のPonyと申します。
宜しくお願いします。 GCが子Formのインスタンスをメモリから解放する タイミングがわからずに困っております。 子FormのClassのコンストラクタ・ディストラクタに ログをいれてインスタンス生成数を管理したいですが、 実際にログを入れてみますと以下のような動作に見えます。 MDI形式のFormの場合、子Formを表示した際に 子Formのクラスにコンストラクタ起動はなされますが、 子Formを閉じた際に、ディストラクタは実行されない。 そのため、同じ子Formを何度も[表示->終了]させた場合、 子Formのインスタンスがいっぱいできてしまうように見えます。 できれば、子Form終了時にメモリ上から解放したいのですが。 可能なのでしょうか。 どなたか、ご教授のほどよろしくお願い致します。 | ||||||||||||
|
投稿日時: 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 を利用する者はメモリのことを考える必要はありません。こちらが小手先にメモリを管理するよりも大抵はより賢く確保と解放を行ってくれるでしょう。 我々が管理するべきなのはメモリではなくインスタンス(の参照)です。 | ||||||||||||
|
投稿日時: 2007-04-02 17:42
・子Formを表示する ・子Formを閉じる ということとインスタンスが生成される/破棄される ということとは直接は関係がありません。 インスタンスが生成されるのはnewしたタイミング(表面上はなんらかのメソッドを 呼び出すことでインスタンスを生成(というか取得)するようなパターンはありますが、 それらもその"なんらかのメソッド"の中でnewしています。) インスタンスが破棄されるのは、インスタンスを参照している変数等が1つもない状態で、 GCが起動したときです。
それで正常です。
明示的な解放手段はありません。 GCにまかせましょう。 #GC.Collectメソッドで明示的にGCを起動させることはできるけれど、 #乱用するようなものではありません。 | ||||||||||||
|
投稿日時: 2007-04-02 17:44
という発想が既にGCを誤解しています。 クラスインスタンスを構成する純粋な「(管理された)メモリ」の管理について、原則として、プログラマが全く考えなくてよいための仕組みがGCです。 「(管理された)メモリ」は、原則としてうっちゃらかしで構いません。 既にコメントが付いていますが、Form を閉じた時点で「解放されるべきモノ」は「メモリ」ではなく、OSが「画面上に表示されるウィンドウというもの」の管理に使用している「ウィンドウハンドル」や、それに関連する「GCとは無関係なモロモロのブツ」です。 こういった、「GCとは無関係なブツ」の解放は、Close() や Dispose() で行われます。 | ||||||||||||
|
投稿日時: 2007-04-02 18:40
早速丁寧なご返信を頂き、ありがとうございます。
たしかにGCの概念、及びFormの操作を誤解しておりました。 #Formを閉じた時点でメモリ自体解放されると思い込んでおりました。 失礼いたしました。 もう少しメモリ管理を勉強してみます。 |
1