【问题标题】:do all local variables go on the stack是否所有局部变量都进入堆栈
【发布时间】:2009-02-01 12:23:32
【问题描述】:

A 与 B 的堆栈和堆上的内存开销是多少

答:

private string TestA()
{
     string a = _builder.Build();
     return a;       
}

乙:

private string TestB()
{
     return _builder.Build();
}

【问题讨论】:

    标签: c# memory


    【解决方案1】:

    是效率问题;两者是相同的,并且在发布模式下会简化为相同的东西。不管怎样,string 是一个引用类型,所以string 本身总是在堆上。堆栈上唯一的东西就是对string 的引用——几个字节(不管字符串长度)。

    "是否所有局部变量都入栈": no;有两个例外:

    • 捕获的变量(匿名方法/lambda)
    • 迭代器块(yield return 等)

    在这两种情况下,背后都有一个编译器生成的类:

    int i = 1;
    Action action = delegate {i++;};
    action();
    Console.WriteLine(i);
    

    类似于:

    class Foo {
        public int i; // yes, a public field
        public void SomeMethod() {i++;}
    }
    ...
    Foo foo = new Foo();
    foo.i = 1;
    Action action = foo.SomeMethod;
    action();
    Console.WriteLine(foo.i);
    

    因此i 在一个对象上,因此在堆上。

    迭代器块的工作方式类似,但使用状态机。

    【讨论】:

      【解决方案2】:

      它们都针对同一事物进行了优化。

      在回答您标题中的问题“是否所有局部变量都进入堆栈”时,简单的答案并不完全正确。无论如何,所有对象都存储在“堆”上(不记得在.NET中是否这样称呼)。 C# 有一个基于分代的垃圾收集器,它知道某些对象只存在很短的时间,因此旨在有效地管理这一点。

      【讨论】:

        猜你喜欢
        • 2015-01-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多