Reputation: 14505
How much memory is used by an empty List or Dictionary? Such as:
List<double> list = new List<double>();
The pointer itself eats at least 32 bits on x86 and 64 of x64 OS, but what about the list itself? With 0 records.
The reason for asking is, can you save some bytes by setting lists to null
?
(Imagine you have a class that contains some List<T>
which in some cases is being used and in other case it is not, in that case having a boolean
like IsEmpty
and null
instead of empty list might save some operating memory. Especially in case you would have thousands of such classes in operating memory, every bit counts.)
Upvotes: 14
Views: 9158
Reputation: 124794
The reason for asking is, can you save some bytes by setting lists to null?
As a general rule (to which, like any rule, there are exceptions), you shouldn't set managed objects to null
to free memory. Instead, leave it to the garbage collector to detect when an object is no longer reachable. In fact, setting a reference to null
may be counter-productive as it can actually slightly extend the lifetime of the object.
An exception might be an edge case where it's worth setting a large object to null
(e.g. a very large list that is a property of another object which for some reason needs to remain reachable), but such cases will be rare and may indicate a "code smell".
Upvotes: 0
Reputation: 23646
Decompiled by 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
...
}
you got total of 20 bytes on x86 (16 for List<T>
members and 4 for metadata reference overhead) and 32 on x64, including reffernce to type of the object, which each object in .net have. This calculation is done roughly not counting alligment.
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
}
44 for x86 and 72 for x64. Again rough calculation, since instances of different objects are required.
Upvotes: 25