.NET数组的内存布局是什么?
以这个数组为例:
Int32[] x = new Int32[10];
我知道数组的大部分是这样的:
0000111122223333444455556666777788889999
其中每个字符是一个字节,并且数字对应于数组中的索引.
另外,我知道所有对象都有一个类型引用和一个syncblock-index,所以上面的内容可以调整为:
ttttssss0000111122223333444455556666777788889999 ^ +- object reference points here
另外,需要存储数组的长度,所以这可能更正确:
ttttssssllll0000111122223333444455556666777788889999 ^ +- object reference points here
这完整吗?数组中是否有更多数据?
我问的原因是我们试图估计一个相当大的数据语料库的几个不同的内存中表示将占用多少内存,并且数组的大小变化很大,因此开销可能有一个在一个解决方案中产生巨大影响,但在另一个解决方
所以基本上,对于一个数组,有多少开销,这基本上是我的问题.
在数组坏队被唤醒之前,解决方案的这一部分是静态构建 - 一次引用 - 通常类型的事情,因此这里不需要使用可增长列表.
检查这一点的一种方法是查看WinDbg中的代码.因此,考虑到下面的代码,让我们看看它是如何出现在堆上的.
var numbers = new Int32[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
首先要做的是找到实例.由于我已将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(每四个字节).
最后四个字节为空.我不完全确定,但我想这必须是在实例用于锁定时存储对syncblock数组的引用的地方.
编辑:首次发布时忘记长度.
列表略有不正确,因为romkyns指出实例实际上从地址-4开始,第一个字段是Syncblock.
好问题.我发现这篇文章包含值类型和引用类型的框图.另见Ritcher所述的这篇文章:
[snip]每个数组都有一些与之关联的额外开销信息.此信息包含数组的等级(维数),数组的每个维度的下限(几乎总是0)以及每个维度的长度.开销还包含数组中每个元素的类型.
好问题!我想亲眼看看,这似乎是一个尝试CorDbg.exe的好机会......
对于简单的整数数组,似乎格式为:
ssssllll000011112222....nnnn0000
其中s是同步块,l是数组的长度,然后是各个元素.看来最后还有一个0,我不知道为什么会这样.
对于多维数组:
ssssttttl1l1l2l2???????? 000011112222....nnnn000011112222....nnnn....000011112222....nnnn0000
其中s是同步块,t是元素的总数,l1是第一维的长度,l2是第二维的长度,然后是两个零?,然后是所有元素的顺序,最后再次为零.
对象数组被视为整数数组,这次内容是引用.锯齿状数组是对象数组,其中引用指向其他数组.