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

C# 空列表或字典的内存使用情况?,c#,memory,C#,Memory,空列表或字典使用了多少内存?例如: List<double> list = new List<double>(); List List=新列表(); 指针本身在x86和64的x64操作系统上至少占用32位,但是列表本身呢?有0条记录 询问的原因是,可以通过将列表设置为null来保存一些字节吗 (假设您有一个类,其中包含一些列表,在某些情况下正在使用,而在另一种情况下则不是,在这种情况下,使用布尔值如IsEmpty和null代替空列表可能会节省一些操作内存。特别是在操作

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

List<double> list = new List<double>();
List List=新列表();
指针本身在x86和64的x64操作系统上至少占用32位,但是列表本身呢?有0条记录

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


(假设您有一个类,其中包含一些
列表
,在某些情况下正在使用,而在另一种情况下则不是,在这种情况下,使用
布尔值
IsEmpty
null
代替空列表可能会节省一些操作内存。特别是在操作内存中有数千个这样的类的情况下,每一位都很重要。)

由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
    ...
}
公共类列表:IList、ICollection、IList、ICollection、IReadOnlyList、IReadOnlyCollection、IEnumerable、IEnumerable
{
私有T[]_items;//x86为4字节,x64为8字节
私有int _size;//4字节
私有int _version;//4字节
[非串行化]
私有对象_syncRoot;//x86为4字节,x64为8字节
私有静态只读T[]\u emptyArray;//每种类型一个
private const int _defaultCapacity=4;//每种类型一个
...
}
x86上总共有20字节(16个用于
列表成员,4个用于元数据引用开销),x64上总共有32字节,包括对对象类型的引用,而.net中的每个对象都有该类型的引用。此计算基本上不计算所有段


公共类字典:。。。
{
私有int[]bucket;//x86为4字节,x64为8字节
private Dictionary.Entry[]entries;//x86为4字节,x64为8字节
私有整数计数;//4字节
私有int版本;//4字节
private int freeList;//4字节
私有int freecont;//4字节
专用IEqualityComparer比较器;//x86为4字节,x64为8字节
private Dictionary.KeyCollection key;//x86为4字节,x64为8字节
private Dictionary.ValueCollection值;//x86为4字节,x64为8字节
私有对象_syncRoot;//x86为4字节,x64为8字节
private const string VersionName=“Version”;//每种类型一个
私有常量字符串HashSizeName=“HashSize”;//每种类型一个
private const string KeyValuePairsName=“KeyValuePairs”;//每种类型一个
私有常量字符串ComparerName=“Comparer”//每种类型一个
}
x86为44,x64为72。由于需要不同对象的实例,因此再次进行粗略计算

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

作为一般规则(与任何规则一样,也有例外),您不应该将托管对象设置为
null
以释放内存。相反,将其留给垃圾收集器来检测对象何时不再可访问。事实上,设置对
null
的引用可能会适得其反


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

我认为你最好的选择是使用像蚂蚁这样的内存分析器,查找这些特定对象及其内存使用情况。我没有钱买蚂蚁和ATM,我在ubuntuI上。我认为在几乎所有情况下,答案都是“太少了,其实不重要”.当涉及到内存时,这对我来说总是很重要的…如果有更少的程序员不关心内存的使用,现代程序就不会那么耗费资源了…@Petr 1.你有多少空列表?除非它是数百万,否则这不会产生明显的差异。2.如果你想减少应用程序的内存消耗,你应该uld使用内存档案器找出占用内存最多的内容。过早优化是浪费时间(最多),这也适用于优化内存。虚拟方法表呢?@PieterGeerkens不是每种类型创建一个吗?
列表也有两个静态变量,但我没有计算它们,因为它们不会影响对象本身的大小。据我所知,.net中的每个对象只有一个引用开销。@svick As OP statIlyaIvanov是的,但是你确定空
List
意味着数组没有实际分配吗?@svick有一个静态空数组
T[0]
,它由所有
T
类型的空列表共享。在默认构造函数中:
\u items=\u emptyArray;
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
}