字符串分配 - Visual studio 内存分析器没有意义

Allocation for strings - Visual studio memory profiler doesn't make sense

Visual studio 内存分析器对我来说没有意义,我正在查看双字符串数组 [10,1000] 并试图弄清楚如何为它分配内存。

  1. "e96" 字符串如何占用 20 个字节?不应该是:成员长度(int 的大小)+ 字符串长度 * char 的大小?所以在这种情况下 4 + 3*2 = 10 字节

我的计算是基于 sizeof string 问题和 Majid 答案 here

  1. 下面的快照已排序,因此数组中的最小字符串大小为 20 字节,总大小如何 = 40KB?它应该是 > 10,000 * 20

我错过了什么?

可以找到代码here

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

先回答你的第二个问题:

请尝试在此行之前拍摄快照:

string[,] mat = GetData();

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

object cellObjectList = GetCells(mat);

您正在截取 mat[] 可能被优化掉的快照。在此时拍摄的快照中查看数组的包含大小。

回答你的第一个问题:

通过调试看到字符串[]内存,

第一个字符串(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

前四个和最后零个字节没有意义?

在转储文件中,第一个字符串元素 0x028923f0 上的 !DumpObject 显示:

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 字节方法 table,4 字节字符串长度,3 x 2 = 6 用于 3 个 unicode 字符)

但是!字符串是 link 类型,因此前四个字节包含 SyncBlockIndex(从地址 - 4 开始)

通过将内存转储到 (0x028923f0 - 4) = 0x028923ec

现在让我们从内存中取出 20 个字节 window

// 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 个字节。

希望这对您有所帮助。