如何在内存中处理数组?

时间:2016-08-30 05:24:39

标签: c# .net

鉴于数组被分配了固定的内存区域,因此完全可以理解数组的长度是不可变的。

假设我有阵列[10] - 这会分配相邻内存的10个插槽吗?并且因为这些插槽是相邻的并且在预定位置处,所以基于索引的查找是快速的。

但是,如果我将复杂的类型放入我的阵列中,大小不均匀会怎样。数组中的实际对象可能属于同一类型,但它们保存的数据大小不同。

.Net如何处理这个问题?我想它会分配非顺序内存来存储对象中的实际数据,但我希望得到一个权威的答案。例如 - 如果对象超过一定大小,它是否只使用非顺序内存?如果对象的大小不断变化,它会继续尝试优化存储位置吗?

考虑这个课程:

public class MyClass
{
    public MyClass[] PotentiallyHugeNestedStructure
}

现在,如果我有一个myclass数组,并在运行时开始分配给子数组和子数组。我最终会得到大量的锯齿状阵列。

那么.net如何在内存中处理这个?

1 个答案:

答案 0 :(得分:3)

在引用类型数组中,数组中的每个元素都包含一个指向托管堆中对象的引用。

所以在数组本身的大小范围内(如你所指定的),在一个基本类型数组上有一个对象数组没有缺点(除了创建对象本身的开销之外,数组元素 reference ,它与内存中数组的大小无关。)

在按索引访问元素的范围内,没有区别,因为两者都是通过索引访问的。确实存在从堆中通过引用检索对象的开销,但它非常快(因为引用通常是表示内存位置偏移的数字)。

下图显示了包含引用类型的数组与包含值类型的数组:

enter image description here

图片来自:CLR Via C#by Jeffrey Richter

myControls是一个对象数组,因此每个元素都保持Null(默认情况下)或对象的引用(对于32位系统为4个字节,对于64位系统为8个字节)。

旁注:图片中指定的开销包含有关数组的信息:

  • 尺寸
  • 每个维度的下限(大多数情况下为0)
  • 阵列的长度。