【问题标题】:How much memory does null pointer use?空指针使用多少内存?
【发布时间】:2011-04-17 15:26:26
【问题描述】:

如果我使用以下代码在 C# 中

Dictionary<int,object> dictionary = new Dictionary<int, object>();
dictionary.Add(1,null);
dictionary.Add(2,new object());
dictionary[2] = null;

分配了多少内存? 字典(字典 [1]、字典 [2])中的每个对象引用是否在堆上采用指针大小(32 位或 64 位)?换句话说,当我执行 dictionary.Add(1,null) 时,CLR 是否会自动在堆上创建 2 个分配,一个用于 int,一个用于空指针?

【问题讨论】:

    标签: c# memory reference memory-management


    【解决方案1】:

    空指针不会分配任何额外的内存来存储堆上的任何东西(因为没有东西可以存储)。但是,您的字典必须存储空指针本身,这与任何其他指针占用的空间一样多。

    每次 add 调用是否导致新的分配(以存储指针)取决于 Dictionary 实现。通常,它有一个内部数组,可以根据需要调整大小。

    在您的示例中,我假设在您创建字典时已经为几个元素分配了足够的空间。所以 add(1, null) 不会再分配空间了。

    更新:default initial capacity for Dictionary 未指定。在 .NET 4.0 中,它实际上从 0 开始,所以第一次添加将创建存储数组。

    【讨论】:

    • 很好的答案,谢谢!我正在学习链表——系统如何处理链表创建无限数量的空指针这一事实?显然,它们并没有全部使用,但是使用数据和节点指针创建节点结构会递归地创建指针节点。这是如何在内存中处理的?每个空指针都有一个内存地址?计算机会根据需要动态分配内存吗?
    【解决方案2】:

    如您所料,空指针本身将占用 4 或 8 个字节,具体取决于它是以 32 位还是 64 位运行。

    在给定的集合中可以有更多。 Dictionary&lt;TKey, TValue&gt; 的实现既使用了一个 Entry&lt;TKey, TValue&gt; 结构数组,其中包含两个 ints 以及键和值,还使用了一个用于索引该数组的整数数组。因此,即使没有“增长空间”(通常有),每个条目也需要 20 字节或 24 字节的内存(而不是键和值的大小所需要的 8 或 12 字节),除了开销之外字典本身(包括每个数组的开销)。

    其他实现和其他集合会有其他开销。他们甚至可能不会为空条目存储nullnull 可能是指示未写入值的有用方式,在这种情况下,特殊值将指示 null 的实际值(在无锁字典实现中特别有用,在这种情况下区分未写入可能很有用只是一个未设置和设置的值,但介于未设置、设置和部分设置的值之间)。

    您真正可以说的是,设置添加值null A) 占用一些内存,B) 不会占用非空值将由对象本身占用的内存。甚至 B) 也不是真的成立,因为如果该对象也存储在其他地方,那么除了引用本身之外,在其他地方有另一个引用不会产生额外的内存成本,这使得它的实际成本与存储 @987654328 相同@。

    【讨论】:

      【解决方案3】:

      我猜是的,因为 null 是一个引用。它指向无处,但您每次都可以用真实的对象引用替换它。

      所以我猜至少分配了 2x64 位,也许字典需要额外的空间。

      【讨论】:

      • 我同意你的回答,但我对此有疑问。指针是 int32 或 int64 变量,因此,即使您将它们设置为 null,我们在内存中也没有其他对象,但仍有 int32 对象作为指针变量是吗?
      • @TJ 博士:指针实际上不是 int32 或 int64 对象,但它们确实具有相同的大小。参照。 Double 的大小与 int64 相同,但类型不同。空指针由 32 或 64 个零位表示,这些位显然必须存储在某个地方。
      猜你喜欢
      • 2019-09-25
      • 2017-06-22
      • 2013-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多