- PR -

[C#] デリゲートをGCの対象から外す方法

投稿者投稿内容
囚人
ぬし
会議室デビュー日: 2005/08/13
投稿数: 1019
投稿日時: 2007-01-26 12:54
面白い展開になってましたね。置いてかれてました。

そもそもメソッドのアドレスって GC によって移動しちゃうんでしょうか。デリゲートインスタンスのアドレスは動いたとしても、Jit Compile されたページが動くんでしょうか。

アンマネージワールドに渡しているのは、デリゲートインスタンスのアドレスか?メソッドのアドレスか?

前者だとしたら、GC による回収は防げても移動は避けられないんですよね(多分)。後者だとしたら、デリゲートインスタンスの寿命は関係ないような気がします。
引用:

(いつのまにか「何が」固定されているのか、に流れてしまいましたが)

それに関して、少なくともマネージ側でデリゲートインスタンスの参照が有効な間は、常にデリゲートに渡されたメソッドを呼び出すはず、というのが僕の主張です。

(なので、元質問者の人が書いているような状況は本来は起きないはずで、起きているとしたら何か原因があるはず)


デリゲートインスタンスが生きている間は、メソッドのアドレスが移動しないという意味でしょうか?
_________________
囚人のジレンマな日々
Tdnr_Sym
ぬし
会議室デビュー日: 2005/09/13
投稿数: 464
お住まい・勤務地: 明石・神戸
投稿日時: 2007-01-26 13:21
こんにちは。

分かりきっていることでしょうが…

オブジェクト指向プログラミングでは、一般に
 (オブジェクト = データ + メソッド)
という認識がされあるように思われます。
オブジェクトとはデータとメソッドがセットになっていると。

では、スタック領域やヒープ領域のメモリ上にオブジェクトが割り当てられた場合を考えてみます。
実際メモリ上に配置されるのは、オブジェクト(データ + メソッド)ではなく
オブジェクトの内のデータ部分だけになるはずです。
(さらにC++の仮想関数テーブルようなデータも含まれるでしょう。)

ではメソッド本体はメモリのどの部分に配置されるでしょう。
Intel CPUの場合で考えますと

・JITコンパイルずみのネイティブコードは、
 CS:コードセグメント(セレクタが示すGDT/LDTで示される)領域にあるはずです。
・スタック領域に配置されたデータは
 SS:スタックセグメントの領域にあるでしょう。
・ヒープ領域に配置されたデータは、おそらく
 DS:データセグメントで示される場所にあると思います。

…という風に、
オブジェクトといってもデータとメソッドはメモリ上の別々の領域にあるはずです。

ガルベージ・コレクタの対象となるのは、データ領域だけですよね。
なので、コード領域にあるメソッドのアドレスが移動することはないのだと思います。

引用:

渋木宏明(ひどり)さんの書き込み (2007-01-26 10:01) より:
で、元々このスレッドで問題にしていたコトは、アンマネージ側に渡ったコールバックアドレスがいつまで有効なのか?ということだったはずです。



よく分からないですが、私の予想では
クラス・アセンブリ・AppDomainがアンロードされるまでは有効な気がします。
なちゃ
ぬし
会議室デビュー日: 2003/06/11
投稿数: 872
投稿日時: 2007-01-26 13:53
引用:

Tdnr_Symさんの書き込み (2007-01-26 13:21) より:
引用:

渋木宏明(ひどり)さんの書き込み (2007-01-26 10:01) より:
で、元々このスレッドで問題にしていたコトは、アンマネージ側に渡ったコールバックアドレスがいつまで有効なのか?ということだったはずです。


よく分からないですが、私の予想では
クラス・アセンブリ・AppDomainがアンロードされるまでは有効な気がします。


前に挙げた、
http://msdn.microsoft.com/msdnmag/issues/06/05/bugbash/default.aspx#S3
を見ると、デリゲートがGCで回数されるまで、と思われます。
っていうかそれはつまり普通にMSDNとかで書いてあるような話と同じ、ですけど。
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2007-01-26 14:01
引用:

よく分からないですが、私の予想では
クラス・アセンブリ・AppDomainがアンロードされるまでは有効な気がします。



それは「コードセクションに x86 のコードがある」だけで「有効」と呼べる状態ではないんじゃないですかねぇ。

aetos
会議室デビュー日: 2005/01/27
投稿数: 16
投稿日時: 2007-01-26 14:06
引用:

ではメソッド本体はメモリのどの部分に配置されるでしょう。
Intel CPUの場合で考えますと

・JITコンパイルずみのネイティブコードは、
 CS:コードセグメント(セレクタが示すGDT/LDTで示される)領域にあるはずです。
・スタック領域に配置されたデータは
 SS:スタックセグメントの領域にあるでしょう。
・ヒープ領域に配置されたデータは、おそらく
 DS:データセグメントで示される場所にあると思います。

…という風に、
オブジェクトといってもデータとメソッドはメモリ上の別々の領域にあるはずです。



すべてのセグメントが、単一の広大なメモリ空間を指し示すような実装がありふれていることを考えれば、スタックもコードも移動しない保証はない気が。
Tdnr_Sym
ぬし
会議室デビュー日: 2005/09/13
投稿数: 464
お住まい・勤務地: 明石・神戸
投稿日時: 2007-01-26 14:38
こんにちは。

引用:

なちゃさんの書き込み (2007-01-26 13:53) より:

前に挙げた、
http://msdn.microsoft.com/msdnmag/issues/06/05/bugbash/default.aspx#S3
を見ると、デリゲートがGCで回数されるまで、と思われます。


引用:

when the delegate is no longer needed by managed code, the garbage collector is free to reclaim it (reclaiming the delegate causes the associated thunk to be freed as well), which will result in the function pointer in unmanaged code becoming invalid



うーん、内容が難しくて意味が良く分からなかったですが、
確かに「アンマネージコードの関数ポインタが無効になる」と書いてありますね。
”サンク”が具体的にどんなものか、少し調査してみようと思います。

引用:

シャノンさんの書き込み (2007-01-26 14:06) より:
すべてのセグメントが、単一の広大なメモリ空間を指し示すような実装がありふれていることを考えれば、



そうなんですか?
GDT,LDT,IDTなどのディスクリプタテーブルで領域サイズを覗かれたのですか?

引用:

スタックもコードも移動しない保証はない気が。


スレッドごとにスタック領域を持っているのは分かりますが、
1プロセスの開始から終了までの間に、
スタックやコードの領域が移動することってあるのでしょうか?
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2007-01-26 14:49
引用:

スレッドごとにスタック領域を持っているのは分かりますが、
1プロセスの開始から終了までの間に、
スタックやコードの領域が移動することってあるのでしょうか?



マネージな世界に関してスタックは微妙かな?と思うところ(*1)がありますが、メモリにロードされたアセンブリのイメージやJITによって生成されたコードが移動されることは、.NET の今のバージョンでは無さそうに思いますねぇ。

*1 マネージスレッドはOSのスレッドそのものではないし、yield なんかの存在を見ると、スタックに関しては「移動」するかどうかはともかく、積極的に管理する(したい)方向なのかな、と。
Tdnr_Sym
ぬし
会議室デビュー日: 2005/09/13
投稿数: 464
お住まい・勤務地: 明石・神戸
投稿日時: 2007-01-26 15:32
こんにちは。

引用:

渋木宏明(ひどり)さんの書き込み (2007-01-26 14:49) より:
*1 マネージスレッドはOSのスレッドそのものではないし、yield なんかの存在を見ると、スタックに関しては「移動」するかどうかはともかく、積極的に管理する(したい)方向なのかな、と。



マネージスレッドは、OSスレッドとは違うんですね!?
ドキュメントを見てもイマイチ理解できないです。
やっぱりソースを見てみないと正体が分かった気になりません。
# Java(sum JVM)では、JavaThreadがOSスレッド(Windows:CreateThread, Solaris/Linux:pthread)で分かりやすいのになぁ。

yieldとはなんでしょうか?(yield returnのこと??)
もうすこし詳しく教えていただけるとうれしいです。

#あれ!?本題とかけ離れてきた気が…

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