2016-01-22 32 views
-3

我有定義爲一類發生什麼事的對象如下:當空分配給它

class Foo 
    { 
     public int Ival { get; set; } 
     public string SVal { get; set; } 
    } 

然後創建一個類的對象;

Foo objFoo = new Foo(); 

很好,所以它會在內存中創建一個類型爲Foo的對象。在這裏,我需要一些澄清/專家意見關於以下疑惑:

  • 當我們分配另一個實例的對象時,當前使用的內存會發生什麼。即objFoo = new Foo();是否會覆蓋或將會移到GC?
  • 將null分配給對象時,內存會發生什麼情況。即, objFoo = null 在我可以訪問新的對象,其中在第二種情況下,訪問值會給我null reference Exception第一種情況。

任何人都可以請給我一個澄清?

+0

這就是你要找的:[自動內存管理](https://msdn.microsoft.com/en-us/library/aa691138(v = vs.71).aspx) – Isuka

+0

讓我知道將其標記爲低質量的原因? –

回答

3

當我們指定另一個實例的對象發生了當前使用的內存是什麼。

objFoo是一個變量,而不是一個對象。

objFoo = new Foo();創建一個新對象(new Foo())並將其指定給objFoo變量。

如果調用objFoo = new Foo();並沒有其他變量是指相同的舊對象,則舊的對象將有資格進行垃圾回收。

垃圾收集不會立即發生,但是當它發生時它將釋放舊對象使用的內存。

有關垃圾回收的更多信息,請參閱this MSDN reference

當空被分配給對象發生了什麼記憶。即,objFoo = null

和我以前的筆記一樣。如果沒有其他變量引用舊對象,則該對象將有資格進行垃圾回收。

在第一種情況下,我可以訪問新的對象,在第二種情況下,訪問值會給我null引用異常。

變量objFoo現在並不是指什麼,這就是爲什麼你所得到的異常,當您嘗試訪問它引用的對象。

+0

很好的解釋。 –

+1

雖然不適用於示例類,但重要的是要注意,如果您的類包含非託管內存(句柄,流,打開文件等),垃圾收集只會自動處理託管內存,那麼您需要實現[ IDisposable](https://msdn.microsoft.com/en-us/library/system.idisposable(v = vs.110).aspx)界面來正確釋放內存。 –

2

當您刪除最後一個引用一個對象(由變量設置爲要麼一個新的對象或null在這種情況下,它基本上是同樣的事情),它被標記爲可用進行垃圾回收。

這並不意味着內存被釋放的時候馬上(雖然這可能發生),所以如果你有訪問存儲器的一些非管理方式,它仍然會顯示爲「有」了一回。

在某個點(您無法確定)釋放內存。

如果您有其他變量/列表等引用該對象,那麼它不符合垃圾回收的條件。

1

開始時,objFoo包含對內存中第一個對象地址的引用。當您創建並分配第二個對象new Foo()時,它將在內存中創建一個新對象,並將新引用放入objFoo中。舊對象,如果不再在代碼中被引用,那麼它就成爲垃圾收集器的候選者。您不會「覆蓋」內存,您只需爲新對象使用另一個內存範圍。

對於你的第二點,它幾乎是一樣的。當您將空引用賦值給objFoo變量時,如果沒有其他變量引用它,則前一個對象將成爲GC的候選對象。由於你的變量實際上引用了一個空值而不是內存中引用的有效Foo對象,所以你會得到這個錯誤。

無論如何,你不知道GC何時會釋放內存。

相關問題