0

In a 32-bit dot-net program I want to add a new field to a class. The field will be a Dictionary< string, object > . Since there will be thousands of instances of this class in existence I wonder how much extra memory this will take. For most of the instances I will probably never populate this field with any value.

How much memory does an empty dictionary take?

Roger Bacon
  • 177
  • 1
  • 1
  • 8
  • I agree that this question has been answered before but one thing to note is would depend on how you write your code. If you're clever and don't initialize the dictionary until it's needed the additional memory will be minimal, just the cost of the reference in the class. If you always instantiate the dictionary then there will be some overhead that you can find in @Pac0's link – amura.cxg Sep 08 '17 at 16:03
  • The dups are not dups. This is a different question. – ispiro Mar 02 '22 at 20:30

3 Answers3

3

For most of the instances I will probably never populate this field with any value.

Then for most instances it will be 4 bytes for the null reference. 8 on 64-bit if you ever adapt it beyond the 32-bit detail you mention in your answer.

How much memory does an empty dictionary take?

That's a different question, since here you seem to have populated it with an empty dictionary, which is not the same as not populating it. The size would vary according to library version but would be around 40 bytes.

Why do this though? If it's rarely used, then rarely set it. Only set it if it's going to be written to, otherwise leave it null, and let the code that looks to read it find a "not present" answer for null the same as it would for empty.

public void Add(string key, object value)
{
  if (_dict == null)
  {
    _dict = new Dictionary<string, object>();
  }

  _dict.Add(key, value);
}

public bool TryGetValue(string key, out object value)
{
  if (_dict != null)
  {
    return _dict.TryGetValue(key, out value);
  }

  value = null;
  return false;
}
Jon Hanna
  • 110,372
  • 10
  • 146
  • 251
  • Thank you (and the others as well). Is it OK to leave the value null if I will be serializing and desrealizing the instances? Deserializing will involve calling GetValue on the SerializationInfo object. Will that be OK if the field is null? – Roger Bacon Sep 08 '17 at 16:53
  • Yes, nulls can be serialised, after all. – Jon Hanna Sep 08 '17 at 17:37
1

By "never populate", I'll assume you mean:

Dictionary<string,object> myDic = null;

Which, if you're concerned about memory usage, may be best - don't instantiate a new dictionary until you know you need one. Then the answer is basically only the memory needed to hold the variable reference in each instance, which is trivial.

If you do need to instantiate the dictionary, the (current) default size is zero elements. You can override that initial capacity, but I won't go down the rabbit hold of algorithms to expand the capacity unless you ask.

So basically, you'll use very little memory either way.

James King
  • 6,233
  • 5
  • 42
  • 63
1

A Dictionary<T, K> is a reference type, which means instances are allocated on the heap and referred to by a handle.

Since you're not populating the field, the handle will retain its default null value. So, the only overhead is the size of the handle itself, which is the same as an IntPtr (32-bits on the 32-bit runtime, and 64-bits on the 64-bit runtime).

This can be verified easily enough by checking the size of the managed heap after allocating a large number of handles:

var start = GC.GetTotalMemory(true);
var handles = new Dictionary<string, object>[100000];
var sizeApprox = (GC.GetTotalMemory(false) - start) / 100000.0;
GC.KeepAlive(handles);
Console.WriteLine("A handle takes {0:0.##} bytes", sizeApprox);
// Prints 4 in x86 mode and 8 in x64 mode
Cameron
  • 96,106
  • 25
  • 196
  • 225