List< object>内存开销 [英] List<object> memory overhead

查看:95
本文介绍了List< object>内存开销的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样的东西:

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.

Now val is always byte[4] and there are around 37000000 elements. So I would think that res should be around 37*10^6 * 4 bytes = 148 MB, but the real memory usage is around 2GB. If I comment res.Add(val); then memory usage is somewhere 100 MB.

那记忆去哪里了?

编辑

我尝试使用uint代替byte [4],但是结果是相同的:

I've tried to use uint instead of byte[4], but the result is the same:

EDIT2

好吧,使用uint代替字节[4] ,用List<uint>()代替List<object>将内存增加到300 MB左右.

Ok, using uint instead of byte[4] and List<uint>() instead of List<object> put the memory to around 300 MB.

推荐答案

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

This is a common problem of allocating large amounts of tiny objects: object overhead, which you can usually disregard, comes into play.

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

37*10^6 * 4 bytes = 148 Mb

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

Assuming that an array of four bytes would occupy four bytes in memory is incorrect. In addition to the payload of four bytes, array object must store array's length, a sync block, and a type pointer. This works out to 12 bytes of overhead on a 32-bit system, or 24 bytes on a 64-bit system.

除了数组对象的各个开销外,您还需要考虑内存分配器的开销,内存对齐的开销和垃圾收集器的开销.综上所述,看到正在使用的总内存增长到2 Gb并非没有道理.

In addition to individual overheads of array objects you need to factor in the overhead of memory allocator, overhead of memory alignment, and overhead of garbage collector. All things taken together, it is not unreasonable to see the total memory in use grow to 2 Gb.

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

One way to fix this is to switch to a list of uints, which do occupy four bytes each. When you need to store four bytes, convert them to uint, and store it in the list. When you need your bytes back, convert uint into a temporary four-byte array. Use BitConverter to deal with converting between uints and arrays of bytes.

这篇关于List&lt; object&gt;内存开销的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆