...

воскресенье, 14 июня 2015 г.

Интересные заметки по C# и CLR (v2.0)

class MyClass
{
    private string _field1 = "Some string 1";
    public string Field2 { get; set; }
}


IL видим два поля:
.field private string '<Field2>k__BackingField'
.field private string _field1


И два метода:
.method public hidebysig specialname instance string get_Field2() cil managed
.method public hidebysig specialname instance void set_Field2(string 'value') cil managed


Посмотрим кто куда попал:
0:003> !do 0000005400006600
Name:        ConsoleApplication1.MyClass
MethodTable: 00007ffa2b5c4378
EEClass:     00007ffa2b6d2548
Size:        32(0x20) bytes
File:        E:\...\ConsoleApplication1.exe
Fields:
              MT    Field   Offset                 Type VT     Attr            Value Name
00007ffa89d60e08  4000002        8        System.String  0 instance 0000005400006620 _field1
00007ffa89d60e08  4000003       10        System.String  0 instance 00000054000035a0 <Field2>k__BackingField

Поля попали прямо к экземпляру, и повлияли на его минимальный размер (32 потому что с 17 по 24 бит заняла первая ссылка (ранее были пустыми), а 25-32 вторая (что бы сохранить порядок их следования есть атрибут). Но методов непосредственно в экземпляре нет, только ссылка на них, и соответственно они не повлияли на его размер.

Посмотрим таблицу методов:

0:003> !dumpmt -md 00007ffa2b5c4378
EEClass:         00007ffa2b6d2548
Module:          00007ffa2b5c2fc8
Name:            ConsoleApplication1.MyClass
mdToken:         0000000002000003
File:            E:\...\ConsoleApplication1.exe
BaseSize:        0x20
ComponentSize:   0x0
Slots in VTable: 7
Number of IFaces in IFaceMap: 0
--------------------------------------
MethodDesc Table
           Entry       MethodDesc    JIT Name
00007ffa89ae6300 00007ffa896980e8 PreJIT System.Object.ToString()
00007ffa89b2e760 00007ffa896980f0 PreJIT System.Object.Equals(System.Object)
00007ffa89b31ad0 00007ffa89698118 PreJIT System.Object.GetHashCode()
00007ffa89b2eb50 00007ffa89698130 PreJIT System.Object.Finalize()
00007ffa2b6e0390 00007ffa2b5c4358    JIT ConsoleApplication1.MyClass..ctor()
00007ffa2b5cc130 00007ffa2b5c4338   NONE ConsoleApplication1.MyClass.get_Field2()
00007ffa2b5cc138 00007ffa2b5c4348   NONE ConsoleApplication1.MyClass.set_Field2(System.String)


А вот и они, оба еще не прошли JIT-компиляцию, кроме конструктора и унаследованных экземплярных методов от System.Object которые Ngen себя при установке .NET.

В заключение этого пункта посмотрим полный размер экземпляра с размером объектов на которые указывают его поля:

MyClass mcClass = new MyClass();
mcClass.Field2 = "Some string 2";

0:003> !objsize 0000005400006600
sizeof(0000005400006600) = 144 (0x90) bytes (ConsoleApplication1.MyClass)


Проверим это посмотрев на размер полей:
0:003> !objsize 0000005400006620
sizeof(0000005400006620) = 56 (0x38) bytes (System.String)
0:003> !objsize 00000054000035a0
sizeof(00000054000035a0) = 56 (0x38) bytes (System.String)


Итого: 56 + 56 + 32 = 144.

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

Комментариев нет:

Отправить комментарий