【问题标题】:Running out of ValueType stack space用完 ValueType 堆栈空间
【发布时间】:2011-06-10 03:33:22
【问题描述】:

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

所以我的问题是这样的;这种行为是否意味着任何 ValueType 变量声明都被限制为 1MB 的存储空间?您在当前范围内声明的 ValueType 越多,调用堆栈可以有效地越小,这是否意味着声明(为了论证)~260,000 个整数将使用您的所有堆栈空间?

【问题讨论】:

  • 理论上您可以通过将值传递给线程的构造函数来增加堆栈的大小。在大多数情况下,您不必这样做。
  • 更多关于值类型和栈的信息:stackoverflow.com/questions/1932155/…
  • @Anthony Pegram:List 是一个引用类型,所以这并不能证明什么。
  • 有缺陷的例子,我承认这一点。

标签: c# memory reference stack value-type


【解决方案1】:

这类问题最有成效的答案通常是去测试。其他人告诉你,你不应该担心这个,他们是对的。所有链接的文章都很棒,值得一读。在大多数实际情况下,您不需要接近 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 的局部变量,你很可能做错了什么。但万一你想知道......现在你知道了。

【讨论】:

  • 太棒了!我想我问这个问题的原因(因为我几乎可以肯定我的假设是正确的)是因为我想不出一种实用的方法来检验这个假设。
  • @Maxim Gershkovich:如果您满意,请考虑接受答案。
  • 没想到这会失败。不过很高兴知道。编写代码时,我在 Visual Studio 中遇到错误。
猜你喜欢
  • 2021-12-31
  • 1970-01-01
  • 1970-01-01
  • 2011-10-11
  • 2011-10-11
  • 1970-01-01
  • 1970-01-01
  • 2018-08-02
  • 2012-12-26
相关资源
最近更新 更多