在C#中,一个结构体需要多少内存?

7
我将处理大约3.2亿个数据点,用于高分辨率波形。每个数据点需要两个浮点数(XY坐标),总共占用8个字节。
为了一次性分配这些内存,我计划使用如下的结构体:
public struct Point
{
    public float X; //4-bytes
    public float Y; //4-bytes.
}

由于结构体是值类型,我假设它仅使用每个变量所需的内存量,以及CLR(公共语言运行时)使用的一些小型固定量。

有没有办法在应用程序运行时计算出一个结构体将使用多少内存?也就是说,如果我知道以下信息:

  • 结构体中有多少个变量。
  • 每个变量使用多少字节。
  • 在某个时间点上有多少个结构体实例。

GC类具有一些内存测量工具。 - j-p
2
一个更加严肃的问题是你计划如何创建320万个这样的对象。在数组中,列表中,... - pm100
1
这里可能会有用:https://blogs.msdn.microsoft.com/joshwil/2005/08/10/bigarrayt-getting-around-the-2gb-array-size-limit/(或搜索词“gcAllowVeryLargeObjects”)。 - spender
不是答案,但我觉得值得指出一个我经常犯的错误:首选数组结构而不是结构体数组。这是一个数学库的问题。如果你必须处理HDF5,AoS将比SoA慢10倍。绘图库倾向于采用plot(xs, ys)而不是plot(xys),机器学习库等等也是如此。对我来说,AoS更合乎逻辑,因为每个点都是一件事情,但它并不会使速度更快。 - Frames Catherine White
1个回答

6
由于结构体是值类型,我假设它只消耗每个变量所需的内存量以及 CLR (Common Language Runtime) 使用的一些小型固定量。

不是这样的。值类型没有任何继承开销。这是无法支持继承的代价。

因此,你只需要为它包含的字段大小付费。


例外情况:

如果你把一个结构体放在类型为Object的变量中,它就会有对象开销:

我在一篇博客文章“关于内存和字符串”中讨论了这个问题。它是与实现相关的,但对于 Microsoft .NET CLR v4,x86 CLR 每个对象的开销为 8 字节,而 x64 CLR 每个对象的开销为 16 字节。

.NET Object 的内存开销是多少?

如果你将其转换为接口类型,同样会发生这种情况。

如果你把一个结构体放在数组中,数组本身有一些对象开销加上一个整数来存储数组的长度。但这是一个固定的成本,无论数组长度如何。

如果你把一个结构体放在List<struct>,你有两个对象:列表和列表使用的数组。因此是每个对象成本的两倍,加上从列表到数组的指针,再加上一个整数来知道当前使用了数组的多少。

如果你把一个结构体放在ListList<object>,你就有了以上开销,再加上列表中每个项的每个对象开销和每个项的每个指针的成本。


1
这意味着如果他使用List<struct>方法,他最终将得到一个结构体的8个字节。 - whymatter
1
请注意,各个字段可能会填充。https://msdn.microsoft.com/zh-cn/library/hx1b6kkd.aspx - Brian Rasmussen
1
如果我们只是拿一个结构体的列表,那么该列表就需要空间(指向该列表的指针、列表对象本身的开销、列表的一些(私有)变量,即_size,_version,_syncRoot),但最大的部分是结构体数组(在列表内),并且该数组本身也会产生一些开销,但然后我们只需要一个结构体的8个字节大小。这意味着,如果他添加了10或320,000,000个结构体,它只会花费 10 * 8 字节 +(所有固定开销)或320,000,000 * 8 字节+(所有固定开销)。 - whymatter
1
据我所了解,struct[]的开销最小,它的大小几乎与byte[]相同(这不是由Brain Rasmussen指出的字段填充造成的)。对于List<struct>来说,不存在“每个对象两倍的成本”,@whymatter是正确的,因为List中只有一个这样的数组(可以通过Reference Source查看)。 - Nicholas Miller
似乎如果不需要调整大小,则最好使用数组。 如果需要调整大小,则可以使用 List<struct>LinkedList<struct>。这两者的区别在于 List<struct> 调整大小较慢,但占用的空间较少,而 LinkedList<struct> 调整大小速度更快,但会消耗大量的内存空间来存储所有的 LinkedListNodes - Nicholas Miller
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接