JavaScript: V8 question: are small integers reused?(JAVASCRIPT:V8问题:小整数可以重复使用吗?)
问题描述
根据V8的博客this article和this existing question,我们知道小整数直接通过指针标记编码到指针中。
SMI的诀窍在于它们不会存储为单独的对象:当您有一个引用SMI的对象时,例如let foo={smi:42},则可以对值42进行SMI编码并直接存储在该对象中(而如果该值为42.5,则该对象将存储一个指向单独&q;HeapNumber&q;的指针)。但由于对象在堆上,所以SMI也在堆上。
这意味着如果我有两个不同的对象具有相同的对象值{smi: 42}。SMI42应该位于堆上的两个不同的内存位置,因为这两个对象位于堆上,并且值42直接编码到指针中,而不是具有额外的存储空间。
但这与Chrome开发工具的内存分析结果相矛盾。给定此代码段
<body>
<button id='btn'>btn</button>
<script>
const btn = document.querySelector('#btn')
function MyObject() {
this.number = 3.14
this.smi = 123
this.undefined = undefined
this.true = true
this.false = false
this.null = null
this.string = 'foo'
}
let obj1
let obj2
btn.onclick = () => {
obj1 = new MyObject()
obj2 = new MyObject()
}
</script>
</body>
我认为smi:123应该位于两个不同的位置,而双精度number = 3.14应该指向相同的数字对象。
smi位于相同的内存位置,而Double不在相同的内存位置。
推荐答案
对@JonasWilms的精彩回答的补充评论:
如果您真正关心幕后发生的事情,我建议您学习如何使用(本机,而不是DevTools)调试器并检查实际内存。DevTool旨在帮助您了解您的应用程序正在做什么,虽然这与揭示幕后发生的事情有很多重叠之处,但这并不完全是一回事,而且很可能会有某些细节(比如SMI的呈现方式)显示出这种差异。我认为堆快照使用raw_address → object ID映射,您所看到的是将SMI放入这样的映射中的自然结果。
对于测试用例的简化版本(只需function MyObject() { this.number = 12.5; this.smi = 23; }),您将在内存中看到以下内容:
(gdb) x/5xw 0x1f010810aedc
0x1f010810aedc: 0x082c7db1 // pointer to map
0x08002249 // pointer to properties (empty array)
0x08002249 // pointer to elements (empty array)
0x0810af71 // pointer to a HeapNumber
0x0000002e // Smi: 23 << 1 == 46 == 0x2e
(gdb) x/5xw 0x1f010810afa4
0x1f010810afa4: 0x082c7db1 // map (same as other object)
0x08002249 // properties
0x08002249 // elements
0x0810afd9 // pointer to a HeapNumber
0x0000002e // Smi: 23 << 1
另外,HeapNumbers可以而且确实可以被重用。我们在本例中没有看到这一点,因为还有另一种机制:对象属性使用可变HeapNumbers。可变使得它们不可共享,在这个玩具示例中,整个方法只是浪费时间和内存;但事实证明,对于典型的使用模式,这是一个有益的权衡,因为它允许更新值(特别是从优化的代码),而不需要每次都分配新的HeapNumber。
如果您只有一个function f() { return 12.5; },它实际上会在每次调用时返回相同的重复使用的HeapNumber。
这篇关于JAVASCRIPT:V8问题:小整数可以重复使用吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:JAVASCRIPT:V8问题:小整数可以重复使用吗?
基础教程推荐
- 当木偶师打开Chrome时,不能使用Chrome扩展 2022-01-01
- 使用 jQuery 在悬停时交换 DIV 类 2022-01-01
- 从快速中间件中排除路由 2022-01-01
- CORS:当凭据标志为真时,无法在 Access-Control-Allow-Origin 中使用通配符 2022-01-01
- 逻辑运算符 ||在 javascript 中,0 代表 Boolean false? 2022-01-01
- HTML5 画布调整为父级 2022-01-01
- 带角度的选项卡:仅使用 $http 在单击时加载选项卡 2022-01-01
- 在 Javascript 中使用 Fetch API 上传文件并显示进度 2022-01-01
- 即使每次插入第一个输入的值不同,第二个输入仍显示相同的输入值 2022-01-01
- 最佳动态 JavaScript/JQuery 网格 2022-01-01
