耗尽ValueType堆栈空间

时间:2011-06-10 03:33:23

标签: c# memory reference stack value-type

我的理解是.Net中的每个新线程都分配1MB of stack space。我的理解是,值类型存储在堆栈而不是堆...

所以我的问题是这个;这种行为是否意味着任何ValueType变量声明限制为1MB的存储空间?你在当前范围内声明的ValueTypes越多,callstack就越有效,并且在某些时候这意味着声明(为了参数)〜260,000 int会使用你所有的堆栈空间?

1 个答案:

答案 0 :(得分: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的本地变量,你很可能做错了。但是如果你想知道的话......现在你知道了。