クラスAがネイティブデータの管理を担当する次のコードを検討してください。そのデータへのポインタは、クラスBに渡されたので、私はBが使用されている間、Aが収集されていないことが必要です。オブジェクトとしての参照をメンバとして保持すると、コレクションが保護されますか?
class A
{
public A(string n)
{
_n = n;
_p = IntPtr.Zero; //acquire native resource
}
public IntPtr GetP()
{
return _p;
}
~A()
{
Console.WriteLine("Free native resource {0}", _n);
}
string _n;
IntPtr _p;
};
class B
{
public B(IntPtr p)
{
_p = p;
}
public B(IntPtr p, Object o)
{
_p = p;
_o = o;
}
public IntPtr GetP()
{
return _p;
}
IntPtr _p;
Object _o;
};
私は「」から「B」への参照を保持していない場合は、 「」期待通りのデータを無効なポインタで私を残している、すぐに収集されます(少なくとも視覚的なスタジオで、モノラルでgcはそれほど熱心ではありません):
static void Main(string[] args)
{
var a = new A("a");
var b = new B(a.GetP());
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine("b._p: {0}", b.GetP());
}
Output:
Free native resource a
b._p: 0
しかし、私は "への参照を保持している場合a 'は' b 'から' a 'は後で使用されなくても終了するまで解放されません。
static void Main(string[] args)
{
var a = new A("a");
var b = new B(a.GetP(), a);
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine("b._p: {0}", b.GetP());
}
Output:
b._p: 0
Free native resource a
私の質問は:この2番目のケースでは、 'a'は 'b'が収集されていない間、生きていることが保証されているか、この動作の実装に依存していますか?後者の場合、どうすればそれを生き続けることができますか?私はいくつかの同様の質問を見てきましたが、私はそれに対して決定的な答えを見つけませんでした。
私は、AがBで参照され、Bが生きているならば、Aも生きていると考えています。私はそれが実装に依存するかどうかはわかりませんが、GCは非常に奇妙で予期しない動作に関係します。 – Glubus
あなたの例では、 'b'はGC.Collectの後で参照するため収集されません。また、' a'は収集されません。 – mg30rg
'a'はアクセス可能な限り*決して*収集されません(*何かがそれにポインターを持っています)。 – Rob