C#では、2つのオブジェクトobj1、obj2がaで構成されてList<string>
いる場合、それらのオブジェクトの両方を同じオブジェクトに割り当てList<string>
ます。
obj1への参照がスコープ外になったが、obj2への参照がスコープ外になった場合、obj1はまだガベージコレクションの対象になりますか、List<string>
それともオブジェクトへの参照がまだあるため、依存関係の問題がありますか?
C#では、2つのオブジェクトobj1、obj2がaで構成されてList<string>
いる場合、それらのオブジェクトの両方を同じオブジェクトに割り当てList<string>
ます。
obj1への参照がスコープ外になったが、obj2への参照がスコープ外になった場合、obj1はまだガベージコレクションの対象になりますか、List<string>
それともオブジェクトへの参照がまだあるため、依存関係の問題がありますか?
obj1自体への参照がない限り、obj1はガベージコレクションの対象になります。
obj1への参照がスコープ外になったが、obj2への参照がスコープ外になった場合、obj1はまだガベージコレクションの対象になりますか、それともListオブジェクトへの参照がまだあるため、依存関係の問題がありますか?
私があなたを正しく理解しているなら、あなたは両方を意味しobj1
、obj2
タイプであり、両方とも同じインスタンスList<string>
を指しています。 List<string>
スコープ外になっても、インスタンスへのアクティブな参照obj1
がまだ存在するため、リストをガベージコレクションすることはできません。obj2
List<string>
obj1がヒープ上の参照型の一部(つまり、そのプロパティの1つ)である場合、obj1が占有していたメモリ空間は、外部オブジェクトの一部としてガベージコレクションされる可能性があります。スタック上の単なる参照である場合、obj1がスコープから外れると、メソッド呼び出しの最後にスタックが巻き戻されるため、GCは関与しません。
obj1は、ヒープ上のオブジェクトへの単なる参照(ある意味ではポインター)であることに注意してください。このオブジェクトは、参照がそれを指していない場合にのみガベージコレクションされる可能性があります。
あなたの場合、ガベージコレクションのobj1
対象である必要があります。
ここを見る必要があります。ガベージコレクションがオブジェクト参照でどのように機能するかを明確に説明しています。Jon Skeet's
answer
のあなたのための素晴らしいチュートリアルObject's Lifetime in C#
。
この質問で定義されているメモリの用途は3つあります。
List<string>
インスタンスへの参照obj1
。List<string>
インスタンスへの参照obj2
。List<string>
。obj1
スコープ外になったがそうでない場合は、obj2
ガベージコレクション後に次のものだけが残ります。
List<string>
と呼ばれるインスタンスへの参照obj2
。List<string>
。ほとんどの場合、C#は参照の概念を抽象化することを覚えておくことが重要です。これにより、参照ではなく、参照であるobj1
と安全に考えることができます。obj2
List<string>
obj1
ヒープ上にある可能性が高いインスタンス自体ではなく、参照がローカル呼び出しスタック内にある可能性があります。したがってobj1
、(参照)は、呼び出しスタックが巻き戻されたときにのみクリーンアップされます。
がリストのメンバーである場合obj1
、親リストがガベージコレクションされるまで、ガベージコレクションに使用できません。
それで:
List<string> l = new List<string>();
string a = "one";
l.Add(a);
{
string b = "two";
l.Add(b);
}
このリストの最後にあるa
、範囲内、b
範囲外ですが、どちらもリストに参照が残っているl
ため、どちらもガベージコレクションの対象にはなりません。