结构和类对象数组的内存分配
最后一天我正在阅读C#参考,在那里我看到了一个声明。 请看下面的陈述。
语境:
对于Point使用结构而不是类可以在运行时执行的内存分配数量有很大差异。 下面的程序创建并初始化一个包含100个点的数组。 将Point实现为类,实例化101个单独的对象 – 一个用于数组,一个用于100个元素。
class Point { public int x, y; public Point(int x, int y) { this.x = x; this.y = y; } } class Test { static void Main() { Point[] points = new Point[100]; for (int i = 0; i < 100; i++) points[i] = new Point(i, i*i); } }
如果将Point实现为结构,如
struct Point { public int x, y; public Point(int x, int y) { this.x = x; this.y = y; } }
只实例化一个对象 – 数组的对象。 Point实例在数组中内联分配。 这种优化可能被滥用。 使用结构而不是类也可以使应用程序运行得更慢或占用更多内存,因为按值传递结构实例会导致创建该结构的副本。
问题:我的问题是如何在值类型和参考类型的情况下完成内存分配?
混淆:为什么在参考指南中提到只有一个对象将被初始化。 根据我对Array中每个对象的理解,将分配一个单独的内存。
编辑:可能重复此问题与jason建议的可能重复的问题略有不同。 我关心的是如何仅在值类型和参考类型的情况下分配内存,而该问题只是解释了值类型和参考类型的概述。
也许通过插图更容易理解引用类型数组和值类型数组之间的区别:
引用类型的数组
每个Point
以及数组都在堆上分配,数组存储对每个Point
引用。 总共需要N + 1个分配,其中N是点数。 您还需要额外的间接访问特定Point
的字段,因为您必须通过引用。
值类型的数组
每个Point
都直接存储在数组中。 堆上只有一个分配。 访问字段不涉及间接。 字段的内存地址可以直接从数组的内存地址,数组中项的索引以及值类型中字段的位置计算。
具有引用类型的数组将由引用数组组成。 每个引用指向包含实际对象的内存区域:
array[0] == ref0 -> robj0 array[1] == ref1 -> robj1 ...
因此,引用数组有一个内存分配(size:arraylength * sizeof(reference)),每个对象有一个单独的内存分配(sizeof(robj))。
具有值类型(如结构)的数组将仅包含对象:
array[0] == vobj0 array[1] == vobj1 ...
所以有jst一个内存分配大小arraylength * sizeof(vobj)