Ivan Stelmakh
Ivan Stelmakh

Reputation: 325

Where does CLR store methods for instances of one type

class MyClass
{
     public string MyProperty { get; set; }

     public void MyMethod()
     {
          //Do something difficult here
          //100500 lines of code here ...
     }
}

We have a lot of instances of MyClass.

Does CLR creates this really memory-expensive MyMethod() for any instance of the class?

Upvotes: 2

Views: 205

Answers (2)

StuartLC
StuartLC

Reputation: 107387

Assuming you mean

Does CLR creates this really memory-expensive MyMethod() for every instance of the class?

No, the code for the methods of classes is only produced for each method once.

However, the data associated with each new instance of a class will be allocated and stored on the managed heap (which defines the this location of the instance), and each method invoked on a class instance will silently pass the this reference (pointer) of the instance as a hidden argument to the method.

Take for instance this snippet:

var foo = new Foo();
var anotherFoo = new Foo();
foo.Bar();
anotherFoo.Bar();

The dissassembly shows how the two this references get passed as parameters to the call to the same Bar method. (in fact, you can see the same Constructor call is also made for both objects).

            var foo = new Foo();
00000038  mov         ecx,592758h 
0000003d  call        FFC8F840
00000042  mov         dword ptr [ebp-4Ch],eax 
00000045  mov         ecx,dword ptr [ebp-4Ch] 
00000048  call        FFCA9F00 
0000004d  mov         eax,dword ptr [ebp-4Ch] 
00000050  mov         dword ptr [ebp-44h],eax ** [ebp-44h] = this for foo 
            var anotherFoo = new Foo();
00000053  mov         ecx,592758h 
00000058  call        FFC8F840
0000005d  mov         dword ptr [ebp-50h],eax 
00000060  mov         ecx,dword ptr [ebp-50h] 
00000063  call        FFCA9F00 
00000068  mov         eax,dword ptr [ebp-50h] 
0000006b  mov         dword ptr [ebp-48h],eax  ** [ebp-48h] = this for anotherFoo
            foo.Bar();
0000006e  mov         ecx,dword ptr [ebp-44h] ** pass foo to `Bar()` across in ecx
00000071  cmp         dword ptr [ecx],ecx 
00000073  call        FFCA9EF8   ** Bar()'s address
00000078  nop 
            anotherFoo.Bar();
00000079  mov         ecx,dword ptr [ebp-48h] ** pass anotherFoo to `Bar()` in ecx
0000007c  cmp         dword ptr [ecx],ecx 
0000007e  call        FFCA9EF8 ** You can see the same "Bar()" address is being called
00000083  nop 

Upvotes: 4

Christos
Christos

Reputation: 53958

No it does not. This method will compiled once, when we have the first call of this method. Then the compiled code will be used by any instance of type MyClass. So any performance hit happens only in the first call of this method, which from IL code will be compiled to native code.

Below, I posted two images that may make this more clear:

enter image description here

and

enter image description here

For further information, please take a look at this book CLR via C#.

Upvotes: 5

Related Questions