空列表或字典的内存使用情况?

时间:2013-04-21 13:31:02

标签: c# memory

空列表或字典使用了多少内存?如:

List<double> list = new List<double>();

指针本身在x86和64位x64 OS上至少占32位,但列表本身呢?有0条记录。

询问的原因是,您可以通过将列表设置为null来保存一些字节吗?

(想象一下,你有一个包含一些List<T>的类,在某些情况下正在使用它,而在其他情况下它不是,在这种情况下,boolean类似IsEmpty和{ {1}}而不是空列表可能会节省一些操作内存。特别是如果你在操作内存中有数千个这样的类,每个位都会计数。)

2 个答案:

答案 0 :(得分:19)

dotPeek反编译:

public class List<T> : IList<T>, ICollection<T>, IList, ICollection, IReadOnlyList<T>, IReadOnlyCollection<T>, IEnumerable<T>, IEnumerable
{
    private T[] _items; //4 bytes for x86, 8 for x64
    private int _size; //4 bytes
    private int _version; //4 bytes
    [NonSerialized]
    private object _syncRoot; //4 bytes for x86, 8 for x64
    private static readonly T[] _emptyArray; //one per type
    private const int _defaultCapacity = 4; //one per type
    ...
}

x86上总计 20 字节(List<T>成员16个,元数据参考开销4个),x64 32 ,包括输入类型对象的内容,.net中的每个对象都有。这种计算大致不包括计数。


public class Dictionary<TKey, TValue> : ...
{
    private int[] buckets; //4 bytes for x86, 8 for x64
    private Dictionary<TKey, TValue>.Entry[] entries; //4 bytes for x86, 8 for x64
    private int count; //4 bytes
    private int version; //4 bytes
    private int freeList; //4 bytes
    private int freeCount; //4 bytes
    private IEqualityComparer<TKey> comparer; //4 bytes for x86, 8 for x64
    private Dictionary<TKey, TValue>.KeyCollection keys; //4 bytes for x86, 8 for x64
    private Dictionary<TKey, TValue>.ValueCollection values; //4 bytes for x86, 8 for x64
    private object _syncRoot; //4 bytes for x86, 8 for x64

    private const string VersionName = "Version"; //one per type
    private const string HashSizeName = "HashSize"; //one per type
    private const string KeyValuePairsName = "KeyValuePairs"; //one per type
    private const string ComparerName = "Comparer"; //one per type
}
对于x86,

44 ,对于x64, 72 。再次粗略计算,因为需要不同对象的实例。

答案 1 :(得分:0)

  

问原因是,可以通过将列表设置为null来节省一些字节吗?

作为一般规则(与任何规则一样,都有例外),不应将托管对象设置为ggplot(mtcars, aes(factor(cyl), fill = factor(vs))) + geom_bar() + theme( legend.position = "top", legend.direction = "horizontal", legend.text = element_blank()) # reset key function to original GeomBar$draw_key <- oldK 来释放内存。而是将其留给垃圾收集器以检测何时不再可访问对象。实际上,设置对null的引用可能会适得其反,因为实际上可以slightly extend the lifetime of the object

一个例外情况可能是值得将大型对象设置为null的极端情况(例如,非常大的列表是另一个对象的属性,出于某种原因,该对象需要保持可访问性),但是这种情况会很少见,可能会显示“代码气味”。