2012-07-25 73 views
5

我在想,具有參考類型和GC的結構?

一個類的實例在堆上。 (裏面的值類型也在堆中)。

相反怎麼辦?

有一個問題here但它沒有提及任何GC相關信息。

所以 - GC如何處理這種情況?

public struct Point 
{ 
object o ; 

    public int x, y; 

    public Point(int p1, int p2) 
    { 
    o = new Object(); 
     x = p1; 
     y = p2;  
    } 
} 

回答

7

Point包括對堆上對象的引用。只要該參考文件不再有該Point的副本,就可以立即收回。注意到:

Point p1 = new Point(1,2); 
Point p2 = p1; 

爲2份,每份用參考相同對象在堆上。如果這些點作爲字段存儲在某個對象的某個對象上,那麼顯然對象的生命週期至少與具有這些字段的對象一樣長。如果這些點只是堆棧中的變量,那麼它會變得更加複雜,因爲GC可能會考慮是否有變量再次讀取。如果不是,變量可能不會有效存在(或者:可能)。

該路徑可能非常間接,但它基本上歸結爲:GC可以從GC根開始到達對象。

+0

馬克我**不要**要問什麼,如果這個結構本身就是一個實例類的字段成員.... :) :) – 2012-07-25 11:48:03

+0

@RoyiNamir簡單,他們都會駐留在堆上; - ) – 2012-07-25 11:50:23

+0

@RoyiNamir GC將問這個問題雖然 – 2012-07-25 11:51:51

3

的GC確實在

  • GC手柄搜索對象根(靜態變量是根這是GC手柄以及)
  • 所有線程堆棧
  • CPU寄存器

在你的情況是通常位於線程棧內的結構,因此被搜索。如果它是盒裝的,則它作爲僞對象駐留在託管堆上。但是你可以放心,這件事是由GC正確計算的。由於它包含一個對象,它不再是一個可變類型,並且不能通過PInvoke傳遞給非託管代碼。

如果您將一個結構傳遞給它,它將被GCed,即使unmaanged調用仍在進行中,只會在發佈版本中才會得到,因爲對於調試構建變量的生存期被延長到該方法留下。在發佈模式中,GC收集更積極。

編輯1: 結構作爲類對象中的成員沒有特殊情況。 GC將檢查嵌入式結構中的所有類字段以獲取類引用。

+0

還有更多http://stackoverflow.com/questions/9938186/gc-roots-misunderstanding – 2017-02-24 10:57:08

0

結構類型的存儲位置可能最好被認爲是與Duck ®品牌膠帶一起固定在一起的存儲位置的集合;固定在一起的存儲位置的性質將是該結構的性質。如果一個結構體存儲在堆棧中,它的字段將被存儲在堆棧中;如果結構存儲在堆對象字段中,則其字段將作爲該堆對象的一部分存儲;等等如果一個結構被存儲在一個可變的存儲位置,其字段(公共或私人)將是可變的(即使該結構不提供突變,複製一個結構到另一個將在相應的領域覆蓋其領域發生變異後前者)。如果結構存儲在不可變的存儲位置,則其所有字段都是不可變的。

如果你用這種方式查看事物,很容易理解一個結構的GC行爲與通過簡單地用單獨的字段替換該結構得到的GC行爲基本相同(唯一重要的地方的行爲是「異常」是與陣列中,由於通常的陣列槽只保持一個項目,而不是字段的集合;沒有相當於一個結構類型的陣列)的非結構。