【发布时间】:2012-07-29 07:07:04
【问题描述】:
这可能是一个非常简单的问题,但我在 SO 上找不到答案,也不知道有人问过答案:
我可以像这样编写一个简单的 c# 方法:
private void foo()
{
int a = 1;
int b = 5;
}
如果 CIL 代码(由编译器创建)由公共语言运行时执行,它将在堆栈顶部创建以下字段,而执行控件位于方法内部:
b = 5
a = 1
但是现在,我将访问名为“a”的字段的方法扩展为:
private void foo()
{
int a = 1;
int b = 5;
Console.WriteLine(a);
}
现在 CLR 必须访问一个不在堆栈顶部的字段,但根据 FILO(先进后出)原则,它必须在访问之前处理所请求字段之上的所有字段。
在请求字段“a”上方的堆栈中名为“b”的字段会发生什么情况?
CLR不能删除它,因为它可能被之后的执行方法使用,那么它会发生什么?
AFAIK,存储字段只有两种方法,堆栈或堆。将它移到堆中没有多大意义,因为这将利用 CLR 的堆栈带来的所有好处。 CLR 是否会创建类似于第二个堆栈的东西?
具体是如何工作的?
-编辑-
也许我解释得不够清楚。
如果我写一个这样的方法:
private void foo()
{
int a = 1;
int b = 5;
Console.WriteLine(a);
Console.WriteLine(b);
}
CLR 首先将 2 个字段写入堆栈,然后再访问它们,但顺序相反。
首先,它必须访问字段“a”,但要访问它,CLR 必须处理位于堆栈上字段“a”之上的字段“b”。它不能只是从堆栈中删除字段“b”,因为它必须在之后访问它。
它是如何工作的?
【问题讨论】:
-
我没有看到您的问题。调用方法会复制参数并附加堆栈帧。原始堆栈帧被保留。
-
优化或不优化?在我看来,
b将被删除,从而消除了问题。 :) -
这四部分系列解释了 C# 中的堆栈和堆,c-sharpcorner.com/uploadfile/rmcochran/…
-
@asawyer:你是对的,因为我的例子没有足够清楚地反映我的问题。我扩展它们以显示我的问题
-
可以肯定的是,您说的是堆栈,因为它实际上是在运行时布置在内存中,而不是 CLI 指令操作的堆栈,对吧?
标签: c# clr heap-memory cil stack-memory