将所有局部变量放在堆栈上

时间:2009-02-01 12:23:32

标签: c# memory

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

A:

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

B:

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

2 个答案:

答案 0 :(得分:7)

提高效率问题;两者是相同的,在发布模式下将减少到相同的东西。无论哪种方式,string都是引用类型,因此string本身始终在堆上。堆栈中唯一的东西是对string的引用 - 几个字节(无论字符串长度)。

“将所有局部变量放在堆栈上”:否;有两个例外:

  • 捕获的变量(匿名方法/ lambdas)
  • 迭代器块(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在一个对象上,因此在堆上。

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

答案 1 :(得分:1)

他们都被优化到同样的事情。

在回答标题中的问题“将所有局部变量放在堆栈上”时,简单的答案并不完全正确。无论如何,所有对象都存储在'堆'上(不记得是否在.NET中调用它)。 C#有一个基于代的垃圾收集器,它意识到某些对象只能在很短的时间内生存,因此可以有效地管理它。