C# 一个int数组使用的内存与一个只有一个int的结构数组使用的内存等效吗?

C# 一个int数组使用的内存与一个只有一个int的结构数组使用的内存等效吗?,c#,.net,struct,C#,.net,Struct,考虑下一个结构 struct Cell { int Value; } 接下来是矩阵定义 var MatrixOfInts = new int[1000,1000]; var MatrixOfCells = new Cell[1000,1000]; 哪一个矩阵将使用更少的内存空间?或者它们是等价的(每个字节)?通过在C#中使用运算符并执行以下代码(在Mono 3.10.0下),我得到以下结果: struct Cell { int Value; }

考虑下一个结构

struct Cell
{
    int Value;
}
接下来是矩阵定义

var MatrixOfInts = new int[1000,1000];
var MatrixOfCells = new Cell[1000,1000];
哪一个矩阵将使用更少的内存空间?或者它们是等价的(每个字节)?

通过在C#中使用运算符并执行以下代码(在Mono 3.10.0下),我得到以下结果:

    struct Cell
    {
        int Value;
    }

    public static void Main(string[] args)
    {
        unsafe
        {
            // result is: 4
            var intSize = sizeof(int);
            // result is: 4
            var structSize = sizeof(Cell);
        }
    }

因此,看起来整数和存储整数的结构消耗相同的内存量,因此我假设数组也需要相同的内存量。

在具有值类型元素的数组中,所有元素都需要完全相同的类型。持有数组的对象需要存储关于其中包含的元素类型的信息,但该信息仅在每个数组中存储一次,而不是每个元素存储一次


请注意,由于数组在.NET Framework中接受特殊处理(与其他集合类型相比),因此结构类型的数组将允许“就地”对其中包含的结构元素进行操作。因此,如果可以限制自己在数组中存储结构(而不是某些其他集合类型),并且可以最大限度地减少对结构实例的不必要复制,那么几乎任何大小的结构都可以有效地运行。如果需要保存一个对象集合,其中每个对象都有四个
Int64
值和四个
Int32
值(总共48字节),那么使用一个包含八个元素的暴露字段结构的数组可能比使用
Int64中的四个元素表示每个对象更高效,语义更清晰[]
和来自
Int32[]
的四个元素,或使用对非共享可变类对象的引用数组。

两者大小相同,因为结构被视为与任何其他值类型一样,并在堆中就地分配

long startMemorySize2 = GC.GetTotalMemory(true);
var MatrixOfCells = new Cell[1000, 1000];
long matrixOfCellSize = GC.GetTotalMemory(true);

long startMemorySize = GC.GetTotalMemory(true);
var MatrixOfInts = new int[1000, 1000];
long matrixOfIntSize = GC.GetTotalMemory(true);

Console.WriteLine("Int Matrix Size:{0}.  Cell Matrix Size:{1}", 
    matrixOfIntSize - startMemorySize, matrixOfCellSize - startMemorySize2);

这里有一些有趣的关于Jeffery Richter如何分配数组

有趣的读法,但是数组会包含每个单元的一些类型信息。考虑一个结构可以实现一个接口,这样我们就可以有…var矩阵=imyStult(100100);(其中单元结构实现IMyStult接口)。然后,也许,CLR会存储关于每个单元格分配了什么实现者的信息。嗯,这是一个有趣的问题,但我想如果你将结构存储为接口,装箱会发生,这会增加内存消耗,因为你的结构会转换为引用类型?如果你存储了结构sim使用它们的值类型(如问题中所述)不需要存储其他类型信息。我们的知识是有限的。我希望熟悉这些低级问题的人,如Eric Lippert或Jon Skeet,能够回答这个问题。数组不存储每个插槽的类型信息。如果将结构存储在接口类型的数组中,结构实例将被装箱,装箱的对象包含特定类型。数组没有它,它只是指向装箱的结构。数组甚至不需要存储元素的类型,因为这包含在它自己的类型中。对于所有类型的数组都是这样的:值、引用、接口等。当然,对于引用和接口类型的数组,数组只有实际项的句柄,而这些项目本身存储着它们各自的类型。@BenVoigt:我想我在什么地方读到了“类型”数组的对象标头中的字段仅将其标识为数组,并且元素类型存储为数组对象本身的一部分。在任何情况下,数组对象都肯定会存储足以标识元素类型的信息,无论是通过将元素类型与其、其自己的元素类型分开存储还是通过为数组维度和元素类型的每个组合声明一个单独的
类型
对象,并让每个数组存储对该对象的引用。同意。我只是说,这不仅仅适用于同质的值类型数组。多态类型的数组仍然只有一个公共元素类型,不同类型的e元素是从每个元素的对象头中查找的。没有什么比证据更好了,它有可复制的提取方法。谢谢!