我有这样的事情:
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。
那么记忆在哪里?
修改
EDIT2
好的,使用uint而不是byte [4] 和 List<uint>()
而不是List<object>
将内存大约300 MB。
答案 0 :(得分:8)
这是分配大量微小对象的常见问题:通常可以忽略的对象开销发挥作用。
37 * 10 ^ 6 * 4字节= 148 Mb
假设四个字节的数组占用内存中的四个字节是不正确的。除了四个字节的有效负载之外,数组对象还必须存储数组的长度,同步块和类型指针。这适用于32位系统上的12字节开销,或64位系统上的24字节。
除了数组对象的单独开销之外,还需要考虑内存分配器的开销,内存对齐的开销以及垃圾收集器的开销。综合所有事情,看到使用的总内存增长到2 Gb是不合理的。
解决此问题的一种方法是切换到uint
列表,每个列表占用四个字节。当您需要存储四个字节时,将它们转换为uint
,并将其存储在列表中。当您需要返回字节时,将uint
转换为临时的四字节数组。使用BitConverter
来处理uint
和byte
数组之间的转换。