内存中可视化的对象结构

时间:2019-02-24 18:48:58

标签: javascript heap-memory

我试图描述如何将Javascript对象放置在内存中。 由于它是一个对象,因此将其存储在内存的堆部分中。它也是键值对的集合。

现在,我有一个问题,JavaScript对象是否实现为链表结构?还是其他?

在这里,我制作了一张图片,该图片从以下代码映射到内存:

var o  = {} 
var o1 = { a: 1, b: o }

enter image description here

因此,关注o1,有一个内存段引用了值1,我们将该空间命名为a。同样,属性b具有指向另一个对象的地址。

我的问题是:这是映射到内存中的Javascript对象的准确表示吗?如果没有,我想念什么?

1 个答案:

答案 0 :(得分:2)

Fundamentall,我认为您的图基本上是正确的,至少在以下主要思想上:对象是已定义的内存区域,具有用于其属性的插槽。

实际内存结构不是由规范定义的,并且可能因JavaScript引擎而异。

规范has to say是什么

  

从逻辑上讲,对象是属性的集合。

......,其中ab之类的数据属性具有名称和值。 1是一个值,一个对象是一个值(稍后会详细介绍)。规范没有涉及如何从各个地方引用值的问题。

实际上,现代JavaScript引擎会创建动态类来优化属性访问,因为属性访问是一种非常常见的操作。它们还通过对象引用处理对象,这些值表示实际对象在引用中内存中其他位置的位置。在现代引擎中,您的对象可能带有ab的内存插槽,它们的大小可能均为64位(但我不知道,可能会有所不同),并且值1直接存储在插槽中,而b的对象引用(再次指向内存中其他位置的对象)也直接存储在插槽中。细节因引擎而异。

例如,您的代码很可能在内存中创建类似这样的内容(省略了很多细节):

                                    +−−−−−−−−−−+
o: Ref33454−−−−−−−−−−−−−−−−−−−−−−+−>| (Object) |
                                 |  +−−−−−−−−−−+
                                 |  +−−−−−−−−−−+
                                 |
                +−−−−−−−−−−−−−−+ |
o2: Ref54612−−−>|   (Object)   | |
                +−−−−−−−−−−−−−−+ |
                | a: 1         | |
                | b: Ref33454  |−+
                +−−−−−−−−−−−−−−+

旁注:

  

由于它是一个对象,它存储在内存的堆部分中。

这不是有效的假设。例如,如果在函数中发生这种情况,并且该函数的使用程度足以使JavaScript引擎决定积极地对其进行优化,则V8使用的这种优化(至少)是(至少)确定对象的寿命是否完全包含在该函数中调用,如果可以,则将其分配到堆栈上,因为堆栈分配和清理非常快。因此,对象完全有可能位于堆栈上,而不是位于堆中(并且,如果我没记错的话,如有必要,可以将其从堆栈中复制到堆中,因为在某些代码路径中它可以保留到函数调用结束之后。)