2013-02-26 22 views
6

MyClass'ın bir örneğinin başka bir yoldan kaynaklanmadığını varsayarsak, buradaki özel statik referans, çöpün toplanmasını engeller mi?Statik alanda kendini referans alan bir sınıf çöp toplayabilir mi?

+1

olası yinelenen (http://stackoverflow.com/questions/6600093/do-static-members-ever-get-garbage-collected) DÜZENLEME: Kısacası, hayır, Yapacağına inanmıyorum. Örneğin, deftere kodu, (heldInstance == null), _instances_ olduğu tek bekletilen referanslar kendisine kendisinden Bunun dışında 'vardır toplanacak _eventually_ eğer kamu yapıcı' vardı olamazdı hiçbir neden yoktur GC tarafından, artık erişilebilir olmadığını belirlediğinde. –

+0

Evet, AppDomain kaldırılmadan hemen önce toplanıyorlar. Sınıf bir finalizer olmadıkça bu tutarsızdır. –

+3

Sınıfın statik alanının, aynı sınıfın * bir örneğine başvurması gerçeği alakasız. Statik alanlar köklerdir; türüne bakılmaksızın onlara koyduğunuz bir şeyi canlı tutacaktır. –

cevap

8

Gönderdiğiniz sınıf çöp toplanmayacak. çıkış olacaktır

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"); 

    } 
} 

: Bir konsol çıkışı ile bunu bir finalizer vererek bu test edebilirsiniz sınıf yalnızca, uygulamanın nihai devrelerde değil toplanan alır demektir

END 
Finalizer called 

düzenli çöp toplama sırasında.

böyle bu sınıfın birden çok örneğini oluşturursanız:

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

sonra en son bir çöp toplanacak bütün hariç.

Sen Çöp toplayıcı nesneleri ulaşılabilir ve olmayanlar da toplayacaktır belirler

Finalizer called 
Finalizer called 
Finalizer called 
END 
Finalizer called 
+1

Bunun yalnızca 'heldInstance' statik olduğu için geçerli olduğunu unutmayın. MyClass' 'örneğidir kendisine bir başvuru olmadığı gerçeğine özel bir şey yoktur. Yani, evet "kendisine referans veren bir sınıf" çöp toplanabilir. Ancak, örnekte sınıf olamaz. – dgvid

2

tanınacak. Bir nesnenin ulaşılabilir olup olmadığını belirlemek için, toplayıcı kökleri ile başlayacaktır. Kökler arasında şu anda değerlendirme yığında olan şeyler var, ancak statik alanlar. Kollektör, nesnelere, köklerden herhangi bir nesneye ve böyle bir nesneden başka bir nesneye ve benzerlerine yapılan referansları takip edecektir. Bu şekilde ziyaret edilen her bir nesneye ulaşılabilir ve bu nedenle canlı tutulur.

Sizin durumunuzda statik alan çöp toplayıcısının köklerinden biridir ve bu nedenle bu alan tarafından (dolaylı olarak) başvurulan herhangi bir nesneyi asla toplamaz. Ancak, alanı null olarak ayarlarsanız, o alan artık örneğe başvurmaz ve örneği toplanabilir. [? Statik üyeler hiç çöp toplanan alır mıyım] arasında

İlgili konular