空数据结构占用多少空间(字节)?

时间:2017-09-08 15:55:28

标签: c# .net memory

在一个32位的dot-net程序中,我想为一个类添加一个新字段。该领域将是一个     的字典< string,object> 。由于存在这个类的数千个实例,我想知道这需要多少额外的内存。对于大多数情况,我可能永远不会使用任何值填充此字段。

空字典需要多少内存?

3 个答案:

答案 0 :(得分:2)

  

对于大多数情况,我可能永远不会用任何值填充此字段。

然后对于大多数实例,空引用将为4个字节。 8位是64位,如果你比你在答案中提到的32位细节更适应它。

  

空字典需要多少内存?

这是一个不同的问题,因为在这里你似乎用一个空字典填充它,这与不填充它不一样。大小会因库版本而异,但大约会有40个字节。

为什么这样呢?如果它很少使用,那么很少设置它。只有在它被写入时才设置它,否则将其保留为null,并让看起来读它的代码找到"不存在"回答null与空的回答相同。

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;
}

答案 1 :(得分:1)

从不填充&#34;,我假设你的意思是:

Dictionary<string,object> myDic = null;

如果您关注内存使用情况,可能最好 - 在您知道需要新字典之前,不要实例化新字典。那么答案基本上只是在每个实例中保存变量引用所需的内存,这是微不足道的。

如果你需要实例化字典,那么(当前)默认大小为零元素。您可以覆盖该初始容量,但除非您提出要求,否则我不会放弃算法的兔子扩展容量。

所以基本上,无论如何,你都会使用很少的内存。

答案 2 :(得分:1)

Dictionary<T, K>是一种引用类型,这意味着实例在堆上分配并由句柄引用。

由于您未填充该字段,因此句柄将保留其默认null值。因此,唯一的开销是句柄本身的大小,它与IntPtr相同(32位运行时为32位,64位运行时为64位)。

通过在分配大量句柄后检查托管堆的大小,可以很容易地验证这一点:

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