5

私は考えていた 、

クラスのインスタンスはヒープ上にあります。(その中の値の型もヒープにあります)。

しかし、反対の場合はどうですか?

ここに 1 つの質問がありますが、GC関連する情報については言及されていません。

では、GC はこの状況をどのように処理するのでしょうか。

public struct Point 
{
object o ;

   public int x, y;

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

3 に答える 3

7

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

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

それぞれがヒープ上の同じオブジェクトへの参照を持つ 2 つのコピーです。これらのポイントがオブジェクトのフィールドとしてどこかに保存されている場合、オブジェクトの寿命は少なくともそれらのフィールドを持つオブジェクトと同じくらい長くなります。これらのポイントがスタック上の変数のみである場合、GC は変数が再度読み取られるかどうかを考慮する可能性があるため、より複雑になります。そうでない場合、変数は実際には存在しない可能性があります (または、存在する可能性があります)。

パスは非常に間接的である可能性がありますが、基本的には、GC ルートから開始して、GC がオブジェクトに到達できるかどうかに帰着します。

于 2012-07-25T11:43:50.790 に答える
3

GC はオブジェクト ルートを検索します。

  • GC ハンドル (静的変数はルートであり、GC ハンドルでもあります)
  • すべてのスレッド スタック
  • CPU レジスタ

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

PInvokes に問題があり、デバッグ ビルドの場合、メソッドが終了するまで変数の有効期間が延長されるため、unmaanged 呼び出しがまだ進行中の場合でも GC が実行されるという問題があります。 . リリース モードでは、GC はより積極的に収集します。

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

于 2012-07-25T11:49:14.353 に答える
0

構造体タイプの保管場所は、Duck® ブランドの粘着テープで留められた保管場所の集まりと考えるのが最適です。一緒に固定された保管場所の性質は、構造体の性質になります。構造体がスタックに格納されている場合、そのフィールドはスタックに格納されます。構造体がヒープ オブジェクト フィールドに格納されている場合、そのフィールドはそのヒープ オブジェクトの一部として格納されます。構造体が変更可能なストレージの場所に格納されている場合、そのフィールド (パブリックまたはプライベート) は変更可能になります (構造体が変更を提供していない場合でも、ある構造体を別の構造体にコピーすると、そのフィールドが対応するもので上書きされることによって後者が変更されます)。前者のフィールド)。構造体が不変の格納場所に格納されている場合、そのすべてのフィールドは不変になります。

物事をそのように見ると、構造体の GC 動作が、単に構造体を個別のフィールドに置き換えるだけで得られる GC 動作と本質的に同じであることが容易に理解できます (動作が「異常である」唯一の重要な場所です)。通常、配列スロットはフィールドのコレクションではなく 1 つの項目のみを保持するため、構造体型の配列に相当する非構造体はありません)。

于 2012-07-25T15:55:09.400 に答える