列出内存开销

我有这样的事情:

List res = new List(); ... while (...) { byte[] val = //get new byte[4] res.Add(val); //if this is commented memory usage goes from 2Gb to 180Mb } return res; 

现在val总是字节[4],大约有37000000个元素。 所以我认为res应该在37 * 10 ^ 6 * 4字节= 148 MB左右,但实际内存使用量约为2GB。 如果我评论res.Add(val); 然后内存使用量大约为100 MB。

那么记忆在哪里?

在此处输入图像描述 在此处输入图像描述

编辑

我试图使用uint而不是byte [4],但结果是一样的: 在此处输入图像描述

EDIT2

好吧,使用uint而不是byte [4] List()而不是List将内存放到大约300 MB。

这是分配大量微小对象的常见问题:通常可以忽略的对象开销发挥作用。

37 * 10 ^ 6 * 4字节= 148 Mb

假设四个字节的数组占用内存中的四个字节是不正确的。 除了四个字节的有效负载之外,数组对象还必须存储数组的长度,同步块和类型指针。 这适用于32位系统上的12字节开销,或64位系统上的24字节。

除了数组对象的单独开销之外,您还需要考虑内存分配器的开销,内存对齐的开销以及垃圾收集器的开销。 综合所有事情,看到使用的总内存增长到2 Gb并不是不合理的。

解决此问题的一种方法是切换到uint列表,每个列表占用四个字节。 当您需要存储四个字节时,将它们转换为uint ,并将其存储在列表中。 当您需要返回字节时,将uint转换为临时的四字节数组。 使用BitConverter来处理uintbyte数组之间的转换。