2016-10-01 2 views
-2

私は奇妙な状況に直面しています。リストに追加されたオブジェクト<T>はGCから集めることができますか? (xamarin forms)

objectがArray(リストのような)に追加されていることがわかっているので、参照カウントが増えてGCから集めることができません。

したがって、私はシングルトンでIList変数(=新しいList of course)を持ち、それにオブジェクトがある場合、オブジェクトはGCから収集できません。

これは間違いありませんか?

+2

オブジェクトへの参照があるため。 –

+0

私はちょうどそれが正しいと知りたければ、他の間違いがあるかどうかを調べなければなりません。ありがとう! –

+0

[ask]をお読みください。 _ "このコードは私が見せてくれないだろうか、私は完全な絵を描くのに十分ではないと言っているのだろうか?_は答えることができない。 – CodeCaster

答えて

2

参照カウントはそれについて考える方法ではありませんが、GCはそのようには機能しません。お互いを参照する2つのオブジェクトを収集することができますが、それを指す他のライブリファレンスはありません。

public void Blah() 
{ 
    var foo1 = new Foo(); 
    var foo2 = new Foo(); 
    foo1.OtherFoo = foo2; 
    foo2.OtherFoo = foo1; 
} //at this point, both foo1 and foo2 are eligible for collection 

オブジェクトの参照カウントがゼロに等しいかどうかをチェックするだけでは、この単純なケースでは切断されません。ライブを参照するライブ(または到達可能な)参照がない場合、オブジェクトはコレクションの対象とみなされます。

あなたの質問に関して、あなたのListが到達可能である限り、その中に含まれるオブジェクトは到達可能であり、したがって収集されません。

public void Blah() 
{ 
    var list = new List<Foo>(); 
    var foo1 = new Foo(); 
    var foo2 = new Foo(); 
    list.AddRange(new[] { foo1, foo2 }); 
} //at this point, foo1, foo2 and list are eligible for collection 
:私はあなたのリストに到達できない場合は、リスト自体、および他のいくつかの参照を介して到達可能ではありません、それに含まれるすべてのオブジェクトは、コレクションのためelegibleであることを、先に説明した内容に基づいて、しかし、気づきますか

リスト自体に含まれるオブジェクトへの参照が存在する場合でも、リスト自体を収集することができます。例えば、以下のコードを検討:

static void Main(string[] args) 
{ 
    var o = new object(); 
    Foo(o); 
    //At this point the list created in Foo(o) is eligible for collection, even if 
    //o is not! Collecting the list does not mean that its contents are collected too. 
    Console.WriteLine(o.ToString()); 
} 

private static void Foo(object o) 
{ 
    var list = new MyList<object>(); 
    list.Add(o); 
} //at this point list is eligible for collection! 

リストは、それが一般的に含まれるオブジェクトへの参照を保持するが、これらのオブジェクトは、コンテナへの参照を保持しないことである点。

もう1つの微妙さ。私の前の例では、収集の適格性をスコープで識別できるかもしれません。それは誤った信念になるでしょう。ランタイムは、スコープ内にあるオブジェクトを確実に収集するのに十分なほどスマートです。正式に正解するには、前の例を次のように書き直す必要があります。

public void Blah() 
{ 
    var list = new List<Foo>(); 
    var foo1 = new Foo(); 
    var foo2 = new Foo(); 
    list.AddRange(new[] { foo1, foo2 }); 
    //at this point, foo1, foo2 and list are eligible for collection 
} 
関連する問題