2011-06-10 157 views
4

我的理解是,.Net中的每個新線程都分配了1MB of stack space。進一步我的理解是價值類型存儲在堆棧,而不是堆...用盡ValueType堆棧空間

所以我的問題是這樣的;這種行爲是否意味着任何ValueType變量聲明都被限制爲1MB的存儲空間?你在當前範圍中聲明的ValueTypes越多,調用堆棧就可以有效地變小,並且在某些時候這意味着聲明(爲了參數)〜260,000個整數將會使用所有的堆棧空間嗎?

+3

請參閱:[價值類型的真相](http://blogs.msdn.com/b/ericlippert/archive/2010/09/30/the-truth-about-value-types.aspx) – 2011-06-10 03:37:09

+0

您可以理論上通過將值傳遞給Thread的構造函數來增加堆棧的大小。在大多數情況下,你不必這樣做。 – vcsjones 2011-06-10 03:37:22

+0

有關值類型和堆棧的更多信息:http://stackoverflow.com/questions/1932155/why-value-types-are-stored-onto-stacks – 2011-06-10 03:40:28

回答

4

對這類問題最有成效的答案通常是去測試。別人告訴你,你不應該擔心這個,他們是沒錯。所有鏈接的文章都很棒,值得一讀。在大多數實際情況下,您不需要接近1MB的局部變量。

但是如果你想知道你真的天氣可以有1MB的局部變量值多少錢? 正如其他人指出的那樣,這是實現細節,並且結果可能會因平臺,編譯器版本,供應商等而有所不同。

讓我們自己測試一下,看看有什麼可能,哪些不可行。我在裝有VS2010和C#4.0編譯器的x64機器上。

這裏是我的代碼:

using System; 

namespace SO6301703 
{ 
    struct s64b 
    { 
     public long f1; 
     public long f2; 
     public long f3; 
     public long f4; 
     public long f5; 
     public long f6; 
     public long f7; 
     public long f8; 
    } 

    struct s256b 
    { 
     public s64b f1; 
     public s64b f2; 
     public s64b f3; 
     public s64b f4; 
    } 

    struct s1kb 
    { 
     public s256b f1; 
     public s256b f2; 
     public s256b f3; 
     public s256b f4; 
    } 

    struct s8kb 
    { 
     public s1kb f1; 
     public s1kb f2; 
     public s1kb f3; 
     public s1kb f4; 
     public s1kb f5; 
     public s1kb f6; 
     public s1kb f7; 
     public s1kb f8; 
    } 

    struct s64kb 
    { 
     public s8kb f1; 
     public s8kb f2; 
     public s8kb f3; 
     public s8kb f4; 
     public s8kb f5; 
     public s8kb f6; 
     public s8kb f7; 
     public s8kb f8; 

    } 

    struct s512kb 
    { 
     public s64kb f1; 
     public s64kb f2; 
     public s64kb f3; 
     public s64kb f4; 
     public s64kb f5; 
     public s64kb f6; 
     public s64kb f7; 
     public s64kb f8; 

    } 

    struct s1Mb 
    { 
     public s512kb f1; 
     public s512kb f2; 

    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      unsafe { Console.WriteLine(sizeof(s1Mb)); } 
      s1Mb test; 
     } 
    } 
} 

當我編譯並運行此代碼,我收到堆棧溢出異常。這意味着至少在一些的情況下確實受到堆棧空間的限制。它的確意味着你擁有的本地變量越多,爲方法調用,遞歸等留下的堆棧越少。

再一次:這些考慮幾乎沒有實際意義。如果你分配1MB的局部變量,你很可能做錯了事情。但是如果你想知道......現在你知道了。

+0

太棒了!我想我問這個問題的原因(因爲我幾乎可以肯定我的假設是正確的)是因爲我想不出一種檢驗假設的實際方法。 – 2011-06-10 05:29:19

+0

@Maxim Gershkovich:如果滿意,請考慮接受答案。 – 2011-06-10 07:31:24

+0

不會期望這會失敗。雖然很高興知道。編寫代碼時,我在Visual Studio中出錯。 – 2011-06-15 00:17:28