List<object> memory overhead

落爺英雄遲暮 提交于 2020-01-13 08:31:05

问题


I have something like this:

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;

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.

So where does the memory go to?

EDIT

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

EDIT2

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


回答1:


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 bytes = 148 Mb

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.

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.

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.



来源:https://stackoverflow.com/questions/43229348/listobject-memory-overhead

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!