繁体   English   中英

为什么基引用没有堆开销?

[英]Why is there no heap overhead for the base reference?

StroustrupFoundations of C++ 中,他提供了一种纯面向对象的语言(第 4 页)。

class complex { double re, im; /* … */ };
complex a[ ] = { {1,2}, {3,4} };

他假设a在纯面向对象的语言是在堆中分配,和a的内存布局的样子: 在此处输入图片说明

可能的大小是3*sizeof(reference)+3*sizeof(heap_overhead)+4*sizeof(double) 假设一个引用是一个词,堆开销是两个词,我们得到的可能大小为 19 个词,与 C++ 的 8 个词进行比较。 这种内存开销伴随着分配和间接访问元素的运行时开销。 对内存的间接访问通常会导致缓存利用率问题并限制 ROMability。

我注意到最上面的引用没有堆开销(白色矩形)。

我想这是一种普遍现象,而不是为纯 OO 示例语言指定的。

但是我找不到任何参考资料(我承认这不是一个对搜索引擎友好的问题)。

更新

感谢您的回答。 但是,我忘了发布我最初的猜测。 抱歉,是我的错。

其实我也想过,因为a本身可能被分配在栈上或其他地方,所以它本身不会有堆开销。 但后来,我注意到 BS 还说:

将此与“纯面向对象语言”的更典型布局进行比较,其中each user-defined object is allocated separately on the heap并通过引用访问...

在第 4 页。

因此,我认为他已将实现限制为仅堆(或无堆栈)。

(当然,也许我对这句话读得太多了。)

顶级引用存在于它所在的任何地方。 这里有几个选项:

  1. 它可以存在于堆栈中。 a中的代码可以表示这样的。
  2. 它嵌入到现有对象中。
  3. 分配的内存仅用于保存句柄。 在这种情况下,它将有内存开销。
  4. 它作为一个全球实体而存在。
  5. 引用可以存在于寄存器中。 代码中的a也可以这样表示,在这种情况下,它既没有堆开销也没有内存开销:相反,它“仅”需要使用寄存器。

在此上下文中的主要实现是这些引用不是实际对象,即您不能拥有对引用的引用。 因此,无需保持参考位置固定。 它们可以是(并且它们在实际表示时是)实际值。 典型实现中引用的值是对象的地址。

其他实体是对象:

  • complex用于创建一个对象,该对象实际上嵌入到奇数double “对象”中,这些对象也是值而不是实际对象。
  • a是此模型中引用两个complex对象的数组对象。

当您存储堆上东西,你得到堆的开销。 这两个complex数值存储在堆上,因此它们会产生开销。 引用数组也存储在堆上,因此会产生开销。

但是,对数组的引用并未存储在堆中。 通常,此引用将作为局部变量放置在堆栈上,或者可以通过使用 CPU 寄存器来优化堆栈存储。 在任何一种情况下,引用本身只是一个本地指针变量,它本身没有堆分配开销。

这里的想法是,顶级引用要么是堆栈上/寄存器中的本地/参数(没有堆开销),要么作为一些更大结构的一部分(反过来可能会在堆上分配,但我们不要在这里计算它的开销,因为它不是特定于这个特定引用的,而是在其他数据成员之间共享的)。

其实我也想过因为a本身可能会被分配在栈上或者其他任何地方,所以它本身不会有堆开销。 但后来,我注意到 BS 还说:

将此与“纯面向对象语言”的更典型布局进行比较,其中each user-defined object is allocated separately on the heap并通过引用访问...

在第 4 页。

因此,我认为他已将实现限制为仅堆(或无堆栈)。

(当然,也许我对这句话读得太多了)

我认为你读得太多了。 Stroustroup 所指的现实世界语言(例如 Python、Java 或 C# - 如果我们将自己限制为装箱类型)确实有一个包含普通引用数组的“常规”堆栈。

complex a[ ] = { {1,2}, {3,4} };

让我们打破这种自下而上的方法。

  1. 您有两个列表初始化的complex对象: Complex{1,2}Complex{3,4}

复杂{双,双}

每个complex对象都有堆的地址(白色)和double值占用的空间(蓝色)。

  1. 接下来是外部{括号,用于列表初始化Complex对象的array

数组 { Complex1, Complex2 }

这有array对象的地址(白色),以及两个Complex对象的两个引用(蓝色)。

  1. 最后, complex a没有开销,因为它只是一个存在于堆栈中的局部变量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM