投稿数 - 437, コメント - 6008, トラックバック - 156

誰も参照していないフォームは、何故 GC の対象にならないのか

ネタ元 http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=28778&forum=7&5

こんな話は大好きだ。

確かに、ローカルスコープで作ったインスタンスは、ローカル変数しか参照していなく、他に誰も参照していなかったら、いつか GC の対象になる。Form とて例外ではなかろう。しかし、実際はそうではない。Form は明確に誰も参照していなくても、GC の対象とならないのだ。(後で述べるが、実際は参照している奴が存在する)

Form に限らずコントロールは全てウィンドウハンドルを持つ。コントロールは全て「ウィンドウ」なのだ。.NET ではウィンドウハンドルを持つウィンドウを「System.Windows.Forms.Control」として扱っている。各コントロールはこのクラスから派生しているわけだ。Form もその一つである。Control は内部に System.Windows.Forms.NativeWindow のインスタンスを持ち、ウィンドウハンドルを管理している。Control は Dispose() 時に NativeWindow.DestroyHandle() を呼んでウィンドウハンドルを破棄しているはずだ。

NativeWindow のヘルプを見ると「ウィンドウは、ウィンドウ ハンドルが関連付けられている場合は、ガベージ コレクションの対象にはなりません。」とある。何故だ?どう実現している?

詳細に調べていくと、NativeWindow は内部に GCHandle のインスタンスを保持していた。NativeWindow がウィンドウハンドルに関連付けられていると GC の対象にならないのは GCHandle が鍵なのだ。

GCHandle.Alloc() で新しい GCHandle を作成する。そして GCHandle.Target にガベージコレクションの対象としたくないインスタンスの参照を設定してやればよいのだ。今回の例で言えば、トップレベルの Form のインスタンスの参照だ。(ここでトップレベルの Form のインスタンスの参照をどのように得ているのかは調査中)

結局、Form は自身が内部に持つ GCHandle に参照される事になる。後は GCHandle が誰かに参照されれば問題は解決だ。

GCHandle は誰に参照されているのか?

これは CLR しか預かり知らぬ所。CLR が管理している領域でもあるのか、GC が管理しているのかは分からない。(情報求ム)とにかく、GCHandle は GCHandle.Alloc() したら誰かに参照されている状態で取得できる。

改めて .NET の設計の巧さに拍手だ。

ウィンドウハンドルに限らず、GCHandle を使えば GC を上手に使いこなす事ができるだろう。

投稿日時 : 2006年2月27日 14:35

フィードバック

# re: 誰も参照していないフォームは、何故 GC の対象にならないのか

やっぱり、囚人さんが釣れると思ったw
2006/02/27 15:02 | じゃんぬ

# re: 誰も参照していないフォームは、何故 GC の対象にならないのか

もう好みがバレているようですね。
2006/02/27 15:16 | 囚人

# re: 誰も参照していないフォームは、何故 GC の対象にならないのか

誘う時にバレているって言ってませんでしたっけ? (w
こうやって Blog で掘り下げて頂くと助かりますね。
2006/02/27 16:02 | じゃんぬ

# re: 誰も参照していないフォームは、何故 GC の対象にならないのか

GC だけに注目しているようなので、ネタ投下 ;-)

モーダレスなフォームである Form1, Form2 が存在し、Form1 上に TextBox1 が配置されている時

TextBox textBox = TextBox1;

Form1.Controls.Remove (textBox);
Form2.Controls.Add (textBox);

が「ちゃんと動く」のは何故でしょうか?

特に、Remove() と Add() の行間に注目です。

Windows には「子ウィンドウ(=コモンコントロールは出来合いの子ウィンドウです)は必ずトップレベルウィンドウに保有されていなければならない」という大原則があるはずなのですが。。。
2006/03/02 11:57 | 渋木宏明(ひどり)

# re: 誰も参照していないフォームは、何故 GC の対象にならないのか

>GC だけに注目しているようなので、ネタ投下 ;-)

む・・・。これは一体…。
ネタ爆弾被弾しました。次回作にご期待ください^^;
2006/03/03 8:52 | 囚人

# 誰も参照していないフォームは、何故 GC の対象にならないのか(その2)

誰も参照していないフォームは、何故 GC の対象にならないのか(その2)
2006/04/10 2:08 | 囚人のジレンマな日々

# thanks for the postmishertAtroro

Useful blog website, keep me personally through searching it, I am seriously interested to find out another recommendation of it.
2010/11/08 22:30 | emt training

コメントの投稿

タイトル  
名前  
URL
コメント