Выделение для строк - Visual Studio профилировщик памяти не имеет смысла - PullRequest
0 голосов
/ 19 апреля 2020

Профилировщик памяти Visual Studio для меня не имеет смысла, я смотрю на массив из двух строк [10,1000] и пытаюсь выяснить, как выделяется память для него.

  1. Как строка "e96" занимает 20 байтов? не должно ли быть: длина члена (размер целого) + длина строки * размер символа? так что в этом случае 4 + 3 * 2 = 10 байтов

Мой расчет основан на размере строкового вопроса и ответе Маджида здесь

Снимок ниже сортируется таким образом, чтобы минимальный размер строки в массиве составлял 20 байтов. Каков общий размер = 40 КБ? это должно быть> 10 000 * 20

Что мне не хватает?

this is the snapshot taken from the heap of the double string array

Код можно найти здесь

string[,] mat = GetData(); // memory allocation is done here.

1 Ответ

1 голос
/ 19 апреля 2020

Сначала отвечая на второй вопрос:

Пожалуйста, попробуйте сделать снимок перед этой строкой:

string[,] mat = GetData();

Console.WriteLine("Please take a snapshot here!");
Console.ReadLine()

object cellObjectList = GetCells(mat);

Вы делаете снимок, где, вероятно, оптимизируется мат [,] , Посмотрите размер вашего массива на снимке, сделанном в этот момент.

Чтобы ответить на ваш первый вопрос:

Отладкой и просмотром строки [,] memory,

Первая строка (это e96) указывает на этот адрес:

a0 6e c1 02 (0x02c1e6a0)

Изучив этот адрес, мы увидим эти 20 байтов.

84 d4 ad 70 03 00 00 00 65 00 39 00 36 00 00 00 00 00 00 00

Первые четыре и последние ноль байтов не имеет смысла?

В файле дампа! DumpObject для первого строкового элемента 0x028923f0 показывает:

0:000> !do 028923f0
Name:        System.String
MethodTable: 70add484
EEClass:     706b4a50
Size:        20(0x14) bytes
File:        C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
String:      e96
Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
70adf2d8  4000273        4         System.Int32  1 instance        3 m_stringLength
70addecc  4000274        8          System.Char  1 instance       65 m_firstChar
70add484  4000278       50        System.String  0   shared   static Empty
    >> Domain:Value  00c33988:NotInit  <<

То есть наша строка должна быть 14 байтов? (Таблица методов 4 байта, длина строки 4 байта, 3 x 2 = 6 для 3 символов Юникода)

Но! строка является типом ссылки, поэтому первые четыре байта содержат SyncBlockIndex (начиная с адреса - 4)

Путем сброса памяти в (0x028923f0 - 4) = 0x028923e c

Теперь давайте возьмем 20 байтов, которые мы извлекли из окна памяти

// e96
00 00 00 80 => SyncBlock for String type
84 d4 ad 70 => Method Table of String class
03 00 00 00 => Number of characters in string (string length = 3)
65 00 => e
39 00 => 9
36 00 => 6
00 00 => Padding it to the nearest 4 bytes, 16 here (excluding sync block)

И у нас есть 20 байтов.

Надеюсь, это поможет.

...