2013-12-18 56 views
2

假設我有以下類:垃圾回收器如何處理靜態類使用的對象?

public class Class1 
{ 
     private Class2 _class2; 

     public void SomeMethod() 
     { 
      _class2 = new Class2();    
     } 
} 

這是我的,當我打電話var instance = new Class1()會發生什麼的理解:

  • 如果它不存在,則在堆上創建了一個新類型的對象爲Class1
  • instance在堆上創建的,它的類型的對象指針指向Class1類型對象

問題1:將一種類型的對象來爲Class2,因爲Class1引用它創建的,儘管我還沒有實例化一個還沒有(假設它不存在,當然)?

現在假設我有以下的靜態類

public static class StaticClass 
{ 
     private static NormalClass _normalClass = new NormalClass(); 
     public static void SomeMethod() 
     { 
      // Does something using _normalClass 
     } 
} 

當我打電話SomeMethod(),在堆上創建StaticClass類型對象。

_normalClass也被創建,因此是NormalClass類型對象。

我知道StaticClass Type對象永遠不會被垃圾收集。任何因爲它持有對_normalClass的引用,那也不會。

問題2:是否收集類型對象垃圾?如果是這樣,NormalClass的類型對象是否可以進行垃圾收集? NormalClass中引用的任何內容的Type對象怎麼樣?

當我創建一個看起來很無辜的靜態類時,我是否有可能填滿了一堆無法收集垃圾的類型對象的大型「鏈」?

+0

就像一個筆記,它可能會有人會抱怨你的靜態類的成員沒有被標記爲靜態的事實。儘管如此,我認爲你有這個觀點。 – Magus

+0

謝謝,編輯得當。 –

+0

您對CLR的運作方式有着非常錯誤的心理模型。 Type對象只有在使用Reflection時纔會創建。有些內部結構會在抖動首次遇到類型時跟蹤類型。他們不是垃圾收集。 –

回答

0

好的,你對CLR如何工作的想法是不正確的。請參考這篇文章在.NET內幕,如果你想充分了解它是如何工作:

http://msdn.microsoft.com/en-us/magazine/cc163791.aspx#S7

首先,讓我們得到您的理解正確:

  1. 除非你使用反射,沒有在堆上創建的類型對象。
  2. 當一個對象被分配時,它有一個「TypeHandle」,它指向關於類型的信息。

現在,您的問題:

答1:它的實例化時

號內存分配發生了Class1的堆上。作爲引用類型的Class2獲取引用指針。因此,分配保存引用指針的內存。期。

當Class2被實例化時,實際存儲的內存(基於字段大小)被分配到堆中。

答2:

是的,但他們是不是你認爲它們是什麼。

難道_normalClass會被垃圾收集嗎?是。如果它在某個時刻設置爲空,它將在GC運行時收集。