检查这一点的一种方法是查看 WinDbg 中的代码。所以给定下面的代码,让我们看看它是如何出现在堆上的。
var numbers = new Int32[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
首先要做的是找到实例。由于我已将其设为本地 in Main()
,因此很容易找到实例的地址。
从地址我们可以转储实际的实例,这给了我们:
0:000> !do 0x0141ffc0
Name: System.Int32[]
MethodTable: 01309584
EEClass: 01309510
Size: 52(0x34) bytes
Array: Rank 1, Number of elements 10, Type Int32
Element Type: System.Int32
Fields:
None
这告诉我们这是我们的 Int32 数组,有 10 个元素,总大小为 52 字节。
让我们转储实例所在的内存。
0:000> d 0x0141ffc0
0141ffc0 [84 95 30 01 0a 00 00 00-00 00 00 00 01 00 00 00 ..0.............
0141ffd0 02 00 00 00 03 00 00 00-04 00 00 00 05 00 00 00 ................
0141ffe0 06 00 00 00 07 00 00 00-08 00 00 00 09 00 00 00 ................
0141fff0 00 00 00 00]a0 20 40 03-00 00 00 00 00 00 00 00 ..... @.........
01420000 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
01420010 10 6d 99 00 00 00 00 00-00 00 01 40 50 f7 3d 03 .m.........@P.=.
01420020 03 00 00 00 08 00 00 00-00 01 00 00 00 00 00 00 ................
01420030 1c 24 40 03 00 00 00 00-00 00 00 00 00 00 00 00 .$@.............
我为 52 个字节插入了括号。
- 前四个字节是对 01309584 处方法表的引用。
- 然后是数组长度的四个字节。
- 接下来是数字 0 到 9(每个四个字节)。
- 最后四个字节为空。我不完全确定,但我想如果实例用于锁定,那一定是对同步块数组的引用的存储位置。
编辑:在第一次发布时忘记了长度。
该列表有点不正确,因为正如 romkyns 指出的那样,实例实际上从地址 4 开始,第一个字段是 Syncblock。