列出<object>内存开销

时间:2017-04-05 11:04:07

标签: c# memory-management

我有这样的事情:

List<object> res = new List<object>();
...
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。

那么记忆在哪里?

enter image description here enter image description here

修改

我尝试使用uint而不是byte [4],但结果是一样的: enter image description here

EDIT2

好的,使用uint而不是byte [4] List<uint>()而不是List<object>将内存大约300 MB。

1 个答案:

答案 0 :(得分:8)

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

  

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

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

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

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