2014-04-22 20 views
3

我從舊的StackOverflow文章中讀取關於何時使用stackalloc的示例。現在這個例子中有我有點納悶:Stackalloc和值類型

public unsafe void DoSomeStuff() 
{ 
    byte* unmanaged = stackalloc byte[100]; 
    byte[] managed = new byte[100]; 

    //Do stuff with the arrays 

    //When this method exits, the unmanaged array gets immediately destroyed. 
    //The managed array no longer has any handles to it, so it will get 
    //cleaned up the next time the garbage collector runs. 
    //In the mean-time, it is still consuming memory and adding to the list of crap 
    //the garbage collector needs to keep track of. If you're doing XNA dev on the 
    //Xbox 360, this can be especially bad. 
} 

現在隨時糾正我,如果我錯了,因爲我仍然在一般C#和編程相當新手。但是不是字節值類型?而不是值類型存儲在他們聲明的位置?這是否意味着在這個例子中,managed也存儲在堆棧中,並且通過擴展當這個堆棧幀結束並且它到達主叫地址時,存儲器被自動清理,因此managed應該以與unmanaged在這個例子中?

回答

1

隔離的字節確實是值類型,但數組是引用類型。此處指向managed的指針存儲在堆棧中,與整個unmanaged變量相同,但在垃圾回收器運行之前,不會回收陣列所使用的內存。

+0

使用數組時,是否存儲在堆上的字節的實際實例? –

+1

是的,每個陣列都分配在一個連續的託管堆內存塊中。 –

4

byte[]類似於stackalloc byte[100],但它代表完全不同的東西。 A byte[]參考保存到堆對象的實例,該對象的類型來自System.Array,而stackalloc byte[100](以及對於該fixed byte[100];)保存100個字節。代碼期望類型byte[]將只接受堆對象引用;它不會直接接受100個字節。與所有參考類型一樣,只要參考本身具有某種參考存在的實例,就會保證存在任何參考類型的實例(如果發現某個對象只能通過弱引用訪問,那麼這些參考將在該對象之前失效不再存在,以維護這個不變)。如果沒有對數組的引用存儲在當前棧幀之外的任何位置,則在棧幀退出後它將不再存在,但如果引用存儲在其他地方,則只要有任何引用,數組就會存活。