2013-02-26 9 views
6
public class MyClass { 
    private static MyClass heldInstance; 

    public MyClass() { 
    heldInstance = this; 
    } 
} 

MyClassのインスタンスが他の方法でルートされていないと仮定すると、プライベート静的参照がガベージコレクションされないようにしますか?静的フィールドで自身を参照するクラスをガベージコレクションできますか?

+1

[静的メンバーはガベージコレクションされていますか?](http://stackoverflow.com/questions/6600093/do-static-members-ever-get-garbage-collected)EDIT:要するに、私はそれが信じられません。たとえば、投稿したコードでは、publicコンストラクタが 'if(heldInstance == null)'を持つことができなかった理由はありません。唯一保持されている参照がそれ自体から_それ自体で_ _収集される_instances_ GCによってアクセスできないと判断された時点で –

+0

はい、AppDomainがアンロードされる直前に収集されます。クラスにファイナライザがない限り、それは重要ではありません。 –

+3

クラスの静的フィールドが同じクラスのインスタンス*を参照しているという事実は無関係です。静的フィールドは根です。彼らはそのタイプに関係なくあなたがそれらに入れたものを生きておくでしょう。 –

答えて

8

投稿したクラスはガベージコレクションされません。あなたは、コンソール出力とそれにファイナライザを与えることによってこれをテストすることができます

public class MyClass 
{ 
    private static MyClass heldInstance; 
    public MyClass() 
    { 
     heldInstance = this; 
    } 
    ~MyClass() 
    { 
     Console.WriteLine("Finalizer called"); 
    } 
} 
class Program 
{ 
    static void Main(string[] args) 
    { 
     var x = new MyClass(); // object created 

     x = null; // object may be eliglible for garbage collection now 

     // theoretically, a GC could happen here, but probably not, with this little memory used 
     System.Threading.Thread.Sleep(5000); 

     // so we force a GC. Now all eligible objects will definitely be collected 
     GC.Collect(2,GCCollectionMode.Forced); 

     //however their finalizers will execute in a separate thread, so we wait for them to finish 
     GC.WaitForPendingFinalizers(); 

     System.Threading.Thread.Sleep(5000); 
     Console.WriteLine("END"); 

    } 
} 

出力は次のようになります。

END 
Finalizer called 

クラスは唯一のアプリケーションの最終ティアダウンで収集されることを意味しません定期的なガベージコレクション中に

あなたは、このようなこのクラスの複数のインスタンスを作成する場合は、次のすべての最も最近のものは、ゴミが収集される以外、その後

var x = new MyClass(); 
x = new MyClass(); 
x = new MyClass(); 
x = new MyClass(); 

を。

あなたは、ガベージコレクタは、オブジェクトが到達可能をしているし、そうでないものを収集するかを決定

Finalizer called 
Finalizer called 
Finalizer called 
END 
Finalizer called 
+1

これは 'heldInstance'が静的な場合にのみ当てはまります。 'MyClass'のインスタンスが自分自身への参照を持っているという事実は特別なことはありません。したがって、「自分自身を参照するクラス」はガベージコレクションされる可能性があります。ただし、この例のクラスではできません。 – dgvid

2

になるだろう。オブジェクトに到達可能かどうかを判断するには、コレクタはルートと呼ばれます。ルーツの中には現在評価スタックにあるものがありますが、のstaticフィールドもあります。コレクタは、ルーツから任意のオブジェクトへの参照、およびそのようなオブジェクトから他のオブジェクトへの参照などに従います。この方法で訪問された各オブジェクトは到達可能であるため、生き続けることができます。

静的フィールドはガベージコレクタのルーツの1つで、そのフィールドによって(間接的に)参照されるオブジェクトは決して収集されません。ただし、フィールドをnullに設定すると、そのフィールドはインスタンスを参照しなくなり、のインスタンスが参照されなくなります。

関連する問題