Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.NET阵列的内存布局_.net_Arrays_Overhead - Fatal编程技术网

.NET阵列的内存布局

.NET阵列的内存布局,.net,arrays,overhead,.net,Arrays,Overhead,.NET阵列的内存布局是什么 以这个数组为例: Int32[] x = new Int32[10]; 我知道阵列的大部分是这样的: 0000111122223333444455556666777788889999 其中每个字符是一个字节,数字对应于数组中的索引 此外,我知道所有对象都有一个类型引用和一个syncblock索引,因此可以将上述内容调整为: ttttssss0000111122223333444455556666777788889999 ^ +-

.NET阵列的内存布局是什么

以这个数组为例:

Int32[] x = new Int32[10];
我知道阵列的大部分是这样的:

0000111122223333444455556666777788889999
其中每个字符是一个字节,数字对应于数组中的索引

此外,我知道所有对象都有一个类型引用和一个syncblock索引,因此可以将上述内容调整为:

ttttssss0000111122223333444455556666777788889999
        ^
        +- object reference points here
此外,需要存储阵列的长度,因此这可能更正确:

ttttssssllll0000111122223333444455556666777788889999
        ^
        +- object reference points here
完成了吗?数组中是否有更多数据

我提出这个问题的原因是,我们试图估计一个相当大的数据语料库的两种不同的内存表示将占用多少内存,数组的大小变化很大,因此开销可能对一种解决方案有很大影响,但对另一种解决方案可能影响不大

所以基本上,对于一个数组,有多少开销,这基本上是我的问题


在数组坏掉之前,解决方案的这一部分是一种静态构建一次引用类型,因此这里不需要使用可增长列表。

数组对象必须存储它有多少维度以及每个维度的长度。因此,至少还有一个数据元素要添加到模型中,数组对象必须存储它有多少维度以及每个维度的长度。因此,至少还有一个数据元素要添加到您的模型中

这是一个很好的问题。我找到了一篇文章,其中包含值类型和引用类型的框图。还可以看到Ritcher在其中指出:

[snip]每个阵列都有一些额外的 相关的开销信息 信息技术此信息包含排名 数组的大小(维数), 每个维度的下界 数组(几乎总是0)和 每个维度的长度。头顶 还包含每个元素的类型 在数组中

好问题。我找到了一篇文章,其中包含值类型和引用类型的框图。还可以看到Ritcher在其中指出:

[snip]每个阵列都有一些额外的 相关的开销信息 信息技术此信息包含排名 数组的大小(维数), 每个维度的下界 数组(几乎总是0)和 每个维度的长度。头顶 还包含每个元素的类型 在数组中


好问题!我想亲自看看,这似乎是一个尝试CorDbg.exe的好机会

对于简单整数数组,格式似乎是:

ssssllll000011112222....nnnn0000
其中s是同步块,l是数组的长度,然后是单个元素。似乎最后有一个0,我不知道为什么

对于多维数组:

ssssttttl1l1l2l2????????
    000011112222....nnnn000011112222....nnnn....000011112222....nnnn0000
其中s是同步块,t是元素总数,l1是第一维的长度,l2是第二维的长度,然后是两个零?,后面依次是所有元素,最后是一个零


对象数组被视为整数数组,这次的内容是引用。锯齿状数组是引用指向其他数组的对象数组。

好问题!我想亲自看看,这似乎是一个尝试CorDbg.exe的好机会

对于简单整数数组,格式似乎是:

ssssllll000011112222....nnnn0000
其中s是同步块,l是数组的长度,然后是单个元素。似乎最后有一个0,我不知道为什么

对于多维数组:

ssssttttl1l1l2l2????????
    000011112222....nnnn000011112222....nnnn....000011112222....nnnn0000
其中s是同步块,t是元素总数,l1是第一维的长度,l2是第二维的长度,然后是两个零?,后面依次是所有元素,最后是一个零


对象数组被视为整数数组,这次的内容是引用。锯齿状数组是引用指向其他数组的对象数组。

检查这一点的一种方法是查看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

检查这一点的一种方法是查看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(每个四个字节)
  • 最后四个字节是nul