首页 > 解决方案 > 内存中可视化的对象结构

问题描述

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

现在,我有一个问题,Javascript 对象是否实现为链表结构?或者是别的什么?

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

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

在此处输入图像描述

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

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

标签: javascriptheap-memory

解决方案


从根本上说,我认为您的图表基本上是正确的,至少在主要思想上,对象是一个已定义的内存区域,其属性具有插槽。

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

规范必须说的是

对象在逻辑上是属性的集合。

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

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

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

                                    +−−−−−−−−−−−+
o: Ref33454−−−−−−−−−−−−−−−−−−−−−−+−>| (对象) |
                                 | +−−−−−−−−−−−+
                                 | +−−−−−−−−−−−+
                                 |
                +−−−−−−−−−−−−−−−+ |
o2: Ref54612−−−>| (对象) | |
                +−−−−−−−−−−−−−−−+ |
                | 答:1 | |
                | b: Ref33454 |−+
                +−−−−−−−−−−−−−−−+

边注:

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

这不是一个有效的假设。例如,如果这发生在一个函数中,并且该函数使用得足够多,以至于 JavaScript 引擎决定积极优化它,那么 V8 使用的一种优化(至少)是确定对象的生命周期是否完全包含在函数中调用,如果是,则将其分配到堆栈上,因为堆栈分配和清理非常快。因此,一个对象完全有可能在堆栈中而不是在堆中(如果我没记错的话,如果有必要,它可能会从堆栈复制到堆中,因为在某些代码路径中它会在函数调用)。


推荐阅读