2012-07-25 10 views
5

私は不思議に思っていました。参照型とGCを持つ構造体?

クラスのインスタンスがヒープ上にあります。 (内部の値型もヒープ内にあります)。

しかし、とは逆に、の場合はどうなりますか?

質問が1つあります。hereGC関連情報はありません。

So - この状況をGCはどのように処理しますか?

public struct Point 
{ 
object o ; 

    public int x, y; 

    public Point(int p1, int p2) 
    { 
    o = new Object(); 
     x = p1; 
     y = p2;  
    } 
} 

答えて

7

Pointには、ヒープ上のオブジェクトへの参照が含まれています。これは、その参照にそのPointが存在しなくなるとすぐにコレクションの対象となります。

Point p1 = new Point(1,2); 
Point p2 = p1; 

ヒープ上同じオブジェクトを参照して2つのコピー、各ある:ことを指摘しました。これらの点がオブジェクトのどこかのフィールドにフィールドとして格納されている場合、オブジェクトの存続期間は少なくともそれらのフィールドを持つオブジェクトと同じくらい長くなります。それらの点がスタック上の変数だけである場合、GCは変数が今までのいずれかが再びと読み取られるかどうかを考慮に入れることができるので、より複雑になります。そうでない場合は、変数が効果的に存在しない可能性があります。

パスは非常に間接的ですが、本質的に次のようになります。GCはGCルートから開始してオブジェクトに到達できます。

+0

marc **この構造体自体がインスタンスクラスのフィールドメンバであるかどうかを尋ねたいです。:) :) –

+0

@RoyiNamir単純に、それらはすべてヒープ上に存在します。 - ) –

+0

@RoyiNamir GCはその質問に –

3

GCは

  • GCハンドル(静的変数は、GCが同様にハンドルされている根である)
  • すべてのスレッドが
  • CPUがで

を登録するスタック内のオブジェクトの根の検索を行いますあなたのケースは通常、スレッドスタック内にある構造体であり、したがって検索されます。ボックス化されている場合は、マネージヒープ上に擬似オブジェクトとして存在します。しかし、あなたはこのことがGCによって正しく数えられていることを保証することができます。オブジェクトを含んでいるので、blittable型ではなく、PInvokeを介してアンマネージコードに渡すことはできません。

Pluvokesに構造体を渡すと、unmanged呼び出しがまだ進行中であってもリリースビルドでしか得られない場合でも問題があります。これは、デバッグビルドのために変数の有効期間が延長されるまでですメソッドは残されます。リリースモードでは、GCはより積極的に収集します。

Edit1: クラスオブジェクトのメンバーとしての構造体は、特別なケースではありません。 GCは、埋め込み構造体のクラス参照のすべてのクラスフィールドも検査します。

+0

http://stackoverflow.com/questions/9938186/gc-roots-misunderstanding –

0

構造体タイプの格納場所は、Duck ®ブランドの粘着テープと一緒に固定された格納場所のコレクションと考えるのが最も良いかもしれません。固定された格納場所の性質は構造体の性質になります。構造体がスタックに格納されている場合、そのフィールドはスタックに格納されます。構造体がヒープオブジェクトフィールドに格納されている場合、そのフィールドはそのヒープオブジェクトの一部として格納されます。等構造体が変更可能な格納場所に格納されている場合、そのフィールド(パブリックまたはプライベート)は変更可能です(構造体が突然変異を提供しない場合でも、構造体を別の構造体にコピーすると、後者のフィールドは対応するフィールドで上書きされます)。前者)。構造体が不変の記憶場所に格納されている場合、そのフィールドはすべて不変です。

構造をGCの振る舞いが本質的に構造体を別々のフィールドで置き換えるだけで得られるGCの振る舞いと同じであることを理解するのは簡単です。通常、配列スロットはフィールドの集合ではなく1つの項目を保持するため、構造体型の配列と同等の非構造体はありません)。

関連する問題