javascript - 内存中可视化的对象结构
问题描述
我试图描绘 Javascript 对象如何放置在内存中的方式。由于它是一个对象,它存储在内存的堆部分。它也是键值对的集合。
现在,我有一个问题,Javascript 对象是否实现为链表结构?或者是别的什么?
在这里,我制作了一张从这段代码映射到内存的图片:
var o = {}
var o1 = { a: 1, b: o }
因此,专注于o1
,有一个内存段引用了该值1
,我们将该空间命名为a
。此外,该属性b
具有另一个对象的地址。
我的问题是:这是映射到内存中的 Javascript 对象的准确表示吗?如果没有,我错过了什么?
解决方案
从根本上说,我认为您的图表基本上是正确的,至少在主要思想上,对象是一个已定义的内存区域,其属性具有插槽。
规范没有定义实际的内存结构,并且可能因 JavaScript 引擎而异。
规范必须说的是
对象在逻辑上是属性的集合。
...像您的数据属性a
和b
具有名称和值的地方。1 是一个值,一个对象是一个值(稍后会详细介绍)。该规范没有涉及如何从各个地方引用值的问题。
实际的现代 JavaScript 引擎会创建动态类来优化属性访问,因为属性访问是一种非常常见的操作。它们还通过对象引用处理对象,这些值表示实际对象在内存中其他位置的引用位置。在现代引擎中,您的对象很可能是用一个内存插槽实现的a
和b
,两者的大小都可能是 64 位(但我不知道,这可能会有所不同),并且值 1 直接存储在插槽中,并且对象引用b
(再次指向内存中其他地方的对象)也直接存储在插槽中。细节会因发动机而异。
因此,例如,您的代码可能会在内存中创建类似这样的内容(省略了很多细节):
+−−−−−−−−−−−+ o: Ref33454−−−−−−−−−−−−−−−−−−−−−−+−>| (对象) | | +−−−−−−−−−−−+ | +−−−−−−−−−−−+ | +−−−−−−−−−−−−−−−+ | o2: Ref54612−−−>| (对象) | | +−−−−−−−−−−−−−−−+ | | 答:1 | | | b: Ref33454 |−+ +−−−−−−−−−−−−−−−+
边注:
由于它是一个对象,它存储在内存的堆部分。
这不是一个有效的假设。例如,如果这发生在一个函数中,并且该函数使用得足够多,以至于 JavaScript 引擎决定积极优化它,那么 V8 使用的一种优化(至少)是确定对象的生命周期是否完全包含在函数中调用,如果是,则将其分配到堆栈上,因为堆栈分配和清理非常快。因此,一个对象完全有可能在堆栈中而不是在堆中(如果我没记错的话,如果有必要,它可能会从堆栈复制到堆中,因为在某些代码路径中它会在函数调用)。
推荐阅读
- pyspark - 在 pyspark 中检查零和空值无法正常工作
- c# - 使用 pulumi 运行 EF Core 迁移
- angular - 如何从 Observable 中获取数据并将其放入 Angular 数组中
- java - 如何识别文件在哪个存储设备中
- c# - 组合视图模型在提交后产生空字段
- math - 如何获得 x、y、z 的每个长度和 p 的度数?
- c++ - 如何确定程序未在 docker 内启动的原因
- windows-10 - Autohotkey:当程序失去焦点时自动最小化程序
- python - Pandas Dataframe 删除新的换行符
- oozie - Splunk 与 Oozie 的集成