CLR - 存储参考地址的位置?

时间:2011-10-30 17:08:14

标签: c# clr

我是编程新手,这给我带来了很多困惑。

假设我们有以下声明:

Int32 i = 1;

i的内容存储在内存中,这将是四个字节:00000000 00000000 00000000 00000001

CLR如何在以后访问此内存位置? CLR是否将地址存储在某个内存块中?

4 个答案:

答案 0 :(得分:4)

System.Int32是值类型,未使用任何引用。

实际上,如果编译器可以找到一个CPU寄存器来保存它,那么局部变量可能永远不会在内存中。

如果它在内存中,它的地址将通过向堆栈指针(ESP)或包含引用类型(C#中的class)对象的地址添加一个偏移量来找到它

在从JIT生成的代码中,值类型的变量与本机代码使用的变量无法区分(没有对象头或类似的东西)。

答案 1 :(得分:3)

编译器会跟踪变量的位置,以便它可以创建以正确方式访问变量的代码。

在这种情况下,您将声明一个局部变量,因此它将在堆栈上分配。

程序不会访问特定地址的变量,而是访问基指针的偏移量,该指针指向当前方法的堆栈帧。

将变量设置为1的代码在编译为32位应用程序的机器代码时可以看起来像这样:

mov dword ptr [ebp-8],1

ebp寄存器指向堆栈帧的顶部,因此i变量在此情况下分配了8个字节。

答案 2 :(得分:2)

假设NORMALLY,如果i是局部变量,它将保存在堆栈中。 .NET的抽象 VM是基于堆栈的。

我要补充一点,在Intel / AMD上i将不会以这样的方式保存:-) Intel / AMD little endian 。所以它将是00000001 00000000 00000000 00000000

我正在混合它......现在...... IL语言和.NET 抽象 VM基于“纯”堆栈,所以有一个堆栈:-)(但是没有寄存器,所以“纯粹”(我希望你知道什么是堆栈)。当代码被JIT打印到您正在使用的计算机的机器代码时,可能i将被放入寄存器或堆栈中。

请注意一般,如果要将值类型(或非引用类型,如果要包含托管/非托管指针/引用)保存在堆栈和/或上,那么错误是错误的错误在寄存器中。它们被保存在保存的地方。例如,类的值类型成员与(in)类一起保存(因此堆中的通常)。 yield函数,异步函数,“普通”方法中的值类型,但被“闭包类型”匿名函数引用,通常保存在堆中的某处。但所有这些都是参考实现细节。

答案 3 :(得分:0)

从我所知道的,实际的堆分配引用存储为双指针(或一些等价物),以便垃圾收集器可以移动内存,而不必影响代码中的任何地方,通过更新指针指向来引用某些内容。 / p>

相关问题