这些对象对堆栈或堆参考? [英] Are these objects's references on the Stack or on the Heap?

查看:124
本文介绍了这些对象对堆栈或堆参考?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我真的AP preciate如果有人可以告诉我,我是否充分理解它:

 类X
{
   A A1 =新的A(); //在栈上的参考,在堆对象值
   a1.VarA = 5; //堆栈 - 值类型
   一个A2 = A1; //在栈上的参考,在堆对象值
   a2.VarA = 10; //堆栈 - 值类型
}

还兼有 A1 A2 引用是在栈上,而他们的对象的价值观是堆。但对于变量,它仍然是纯粹的价值类型?

  A级
{
   INT瓦拉;
}


解决方案

您是想询问的的实施细则的,所以答案将取决于具体的实施问题。让我们考虑一个版本的程序,实际上编译:

  A级{公众诠释翻; }
X类
{
    静态无效的主要(字串[] args)
    {
        A A1 =新的A();
        a1.VarA = 5;
        一个A2 = A1;
        a2.VarA = 10;
    }
}

下面是微软的CLR 4.0个究竟,运行C#4.0,在调试模式下。

此时堆栈帧指针已经被复制到寄存器EBP:

下面我们分配堆内存为新对象。

  A A1 =新的A();
MOV ECX,382518h
调用FFE6FD30

这是返回到EAX堆对象的引用。我们存储在堆栈槽EBP-48,这是不使用任何名称相关联的临时时隙的基准。请记住,A1尚未初始化

  MOV DWORD PTR [EBP-48小时],EAX

现在我们把我们只是存储在堆栈上的引用,并将其复制到ECX,将被用于这个指针调用构造函数。

  MOV ECX,DWORD PTR [EBP-48小时]

现在我们调用构造函数。

 调用FFE8A518

现在我们复制存储在临时栈槽到寄存器EAX再次参考。

  MOV EAX,DWORD PTR [EBP-48小时]

现在我们复制EAX参考进栈槽EBP-40,这是A1。

  MOV DWORD PTR [EBP-40H],EAX

现在,我们必须取A1到EAX:

  a1.VarA = 5;
MOV EAX,DWORD PTR [EBP-40H]

记住,EAX现在是由A1引用的东西堆分配数据的地址。那个东西的瓦拉是4个字节到对象,所以我们店5成:

  MOV DWORD PTR [EAX + 4],5

现在我们做的栈槽的基准为A1到EAX的副本,然后复制成A2叠插槽,这是EBP-44。

  A A2 = A1;
MOV EAX,DWORD PTR [EBP-40H]
MOV DWORD PTR [EBP-44H],EAX

而现在,你会再次想到我们得到a2为到EAX,然后顺从参考在四个字节写入0x0A的进入翻:

  a2.VarA = 10;
MOV EAX,DWORD PTR [EBP-44H]
MOV DWORD PTR [EAX + 4],0AH

所以回答你的问题是,对象引用存储在堆栈在三个地方:EBP-44,EBP-48和EBP-40。它们被存储在eax中和ECX寄存器。对象包括外地的内存,存储在托管堆上。这一切都是在x86上的调试版本微软CLR 4.0版的。如果你想知道的东西是如何存储在堆栈,堆和寄存器在其他一些配置,也可能是完全不同的。参考文献都可能被存储在堆上,或所有在寄存器中;有可能是没有堆栈可言。这完全取决于JIT编译器的作者决定如何执行的IL语义。

I would really appreciate if someone could tell me whether I understand it well:

class X
{
   A a1=new A(); // reference on the stack, object value on the heap
   a1.VarA=5;    // on the stack - value type
   A a2=a1;      // reference on the stack, object value on the heap
   a2.VarA=10;   // on the stack - value type         
}

Also both a1 and a2 references are on the stack, while their "object" values are on the heap. But what about VarA variable, its still pure value type?

class A
{
   int VarA;
}

解决方案

You are asking questions about implementation details, so the answer will depend upon the particular implementation. Let's consider a version of your program that actually compiles:

class A { public int VarA; }
class X
{
    static void Main(string[] args)
    {
        A a1 = new A();
        a1.VarA = 5;
        A a2 = a1;
        a2.VarA = 10;
    }
}

here's what happens on Microsoft's CLR 4.0, running C# 4.0, in Debug mode.

At this point the stack frame pointer has been copied into register ebp:

Here we allocate heap memory for the new object.

A a1 = new A();
mov         ecx,382518h 
call        FFE6FD30 

That returns a reference to a heap object in eax. We store the reference in stack slot ebp-48, which is a temporary slot not associated with any name. Remember, a1 has not been initialized yet.

mov         dword ptr [ebp-48h],eax 

Now we take that reference we just stored on the stack and copy it into ecx, which will be used for the "this" pointer to the call to the ctor.

mov         ecx,dword ptr [ebp-48h] 

Now we call the ctor.

call        FFE8A518 

Now we copy the reference stored in the temporary stack slot into register eax again.

mov         eax,dword ptr [ebp-48h] 

And now we copy the reference in eax into stack slot ebp-40, which is a1.

mov         dword ptr [ebp-40h],eax 

Now we must fetch a1 into eax:

a1.VarA = 5;
mov         eax,dword ptr [ebp-40h] 

Remember, eax is now the address of the heap-allocated data for the thing referenced by a1. The VarA field of that thing is four bytes into the object, so we store 5 into that:

mov         dword ptr [eax+4],5 

Now we make a copy of the reference in the stack slot for a1 into eax, and then copy that into the stack slot for a2, which is ebp-44.

A a2 = a1;
mov         eax,dword ptr [ebp-40h] 
mov         dword ptr [ebp-44h],eax 

And now as you'd expect again we get a2 into eax and then deference the reference four bytes in to write 0x0A into the VarA:

a2.VarA = 10;
mov         eax,dword ptr [ebp-44h] 
mov         dword ptr [eax+4],0Ah

So the answer to your question is that references to the object are stored in the stack in three places: ebp-44, ebp-48 and ebp-40. They are stored in registers in eax and ecx. The memory of the object, including its field, is stored on the managed heap. This is all on x86 in the debug build, of Microsoft's CLR v4.0. If you want to know how stuff is stored on the stack, heap and registers in some other configuration, it could be completely different. References could all be stored on the heap, or all in registers; there might be no stack at all. It totally depends on how the authors of the jit compiler decided to implement the IL semantics.

这篇关于这些对象对堆栈或堆参考?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆